package com.fjhx.customer.service.customer.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.area.utils.CustomizeAreaUtil;
import com.fjhx.common.entity.coding.bo.CustomerCodeAndCountryId;
import com.fjhx.common.service.coding.CodingRuleCustomerService;
import com.fjhx.customer.entity.customer.dto.CustomerDto;
import com.fjhx.customer.entity.customer.dto.CustomerSelectDto;
import com.fjhx.customer.entity.customer.po.Customer;
import com.fjhx.customer.entity.customer.po.CustomerFollowRecords;
import com.fjhx.customer.entity.customer.po.CustomerTop;
import com.fjhx.customer.entity.customer.po.CustomerUser;
import com.fjhx.customer.entity.customer.vo.CustomerVo;
import com.fjhx.customer.mapper.customer.CustomerMapper;
import com.fjhx.customer.service.customer.CustomerFollowRecordsService;
import com.fjhx.customer.service.customer.CustomerService;
import com.fjhx.customer.service.customer.CustomerTopService;
import com.fjhx.customer.service.customer.CustomerUserService;
import com.fjhx.customer.utils.code.CodeEnum;
import com.fjhx.tenant.entity.dict.dto.DictTenantDataSelectDto;
import com.fjhx.tenant.entity.dict.vo.DictTenantDataVo;
import com.fjhx.tenant.service.dict.DictTenantDataService;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.system.utils.UserUtil;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 客户表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-04
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService, CodingRuleCustomerService {
    @Autowired
    private CustomerUserService customerUserService;
    @Autowired
    private CustomerFollowRecordsService customerFollowRecordsService;
    @Autowired
    private CustomerTopService customerTopService;

    @Autowired
    private DictTenantDataService dictTenantDataService;


    /**
     * 查询客户的列表
     *
     * @param dto
     * @return
     */
    @Override
    public Page<CustomerVo> getPage(CustomerSelectDto dto) {
//        LambdaQueryWrapper<Customer> wrapper = Wrappers.<Customer>lambdaQuery();
        IWrapper<CustomerVo> wrapper = IWrapper.getWrapper();
        //客户来源查询
        wrapper.eq("c", Customer::getSource, dto.getSource());
        //客户类型查询
        wrapper.eq(Customer::getStatus, dto.getStatus());
        //国家ID查询
        wrapper.eq(Customer::getCountryId, dto.getCountryId());
        //省份ID查询
        wrapper.eq(Customer::getProvinceId,dto.getProvinceId());
        //城市ID查询
        wrapper.eq(Customer::getCityId,dto.getCityId());
        //客户代码
        wrapper.like(Customer::getCustomerCode,dto.getCustomerCode());
        //客户名称
        wrapper.like(Customer::getName,dto.getName());

        //业务员查询
        wrapper.eq(Customer::getUserId,dto.getName());

        //客户标签查询（多个标签用逗号隔开）
        if(StringUtils.isNotEmpty(dto.getTag())){
            List<String> tagList = Arrays.asList(dto.getTag().split(","));
            tagList.forEach(tag->wrapper.like(Customer::getTag,tag));
        }

        //客户状态（0：公海客户  1：私海客户）(业务员ID为null为公海客户，业务员ID不为null为私海客户)
        if (ObjectUtil.isNotEmpty(dto.getType())) {
            //私海客户查询
            if (dto.getType().equals("1")) {
                wrapper.isNotNull("c.user_id");
            } else if (dto.getType().equals("0")) {
                wrapper.and(wrapper1 -> wrapper1.isNull("c.user_id").or().eq(Customer::getUserId, ""));
            }
        }


        //置顶条件
        List<Long> customerIds = customerTopService.listObject(CustomerTop::getCustomerId, q -> q.eq(CustomerTop::getUserId,
                SecurityUtils.getUserId()));
        if (ObjectUtil.isNotEmpty(customerIds)) {
            String join = StringUtils.join(customerIds, ",");
            wrapper.orderByDesc("id IN ( " + join + " )");
        }
        wrapper.orderByDesc(Customer::getUpdateTime);
        wrapper.orderByDesc(Customer::getCreateTime);

        Page<CustomerVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);

        //复制城市信息
        List<CustomerVo> records = page.getRecords();
        CustomizeAreaUtil.setAreaName(records);
        //赋值客户跟进记录
        for (CustomerVo record : records) {
            List<CustomerFollowRecords> customerFollowRecordsList = customerFollowRecordsService.list(q ->
                    q.eq(CustomerFollowRecords::getCustomerId, record.getId())
                            .orderByDesc(CustomerFollowRecords::getDate).last("limit 3"));
            record.setCustomerFollowRecordsList(customerFollowRecordsList);
        }

        //赋值是否置顶
        for (CustomerVo record : records) {
            record.setIsTop(customerIds.contains(record.getId()) ? 1 : 0);
        }

        return page;
    }

    /**
     * 查询客户的详情
     *
     * @param id
     * @return
     */
    @Override
    public CustomerVo detail(Long id) {
        //查询客户表的信息
        Customer Customer = this.getById(id);
        CustomerVo result = BeanUtil.toBean(Customer, CustomerVo.class);
        if (ObjectUtil.isEmpty(result)) {
            throw new ServiceException("没有找到该用户信息");
        }
        //查询客户-联系人表的信息
        List<CustomerUser> customerUserList = customerUserService.list(Wrappers.<CustomerUser>lambdaQuery()
                .eq(CustomerUser::getCustomerId, result.getId()));
        result.setCustomerUserList(customerUserList);
        CustomizeAreaUtil.setAreaName(result);
        return result;
    }

    /**
     * 添加客户表的数据
     *
     * @param customerDto
     */
    @Override
    @DSTransactional
    public void add(CustomerDto customerDto) {

        CustomizeAreaUtil.setAreaId(customerDto);

        customerDto.setCode(CodeEnum.CUSTOMER.getCode());
        this.save(customerDto);
        //添加库户-联系人表的信息
        saveCustomerUse(customerDto);
    }

    /**
     * 修改客户表的数据
     *
     * @param customerDto
     */
    @DSTransactional
    @Override
    public void edit(CustomerDto customerDto) {

        CustomizeAreaUtil.setAreaId(customerDto);

        // 修改客户表的信息
        this.updateById(customerDto);
        // 删除客户-用户表的信息
        customerUserService.remove(Wrappers.<CustomerUser>lambdaQuery().eq(CustomerUser::getCustomerId, customerDto.getId()));
        // 添加客户-联系人表的信息
        saveCustomerUse(customerDto);
    }

    /**
     * 删除客户表的数据
     *
     * @param
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void delete(Long id) {
        //删除客户表的数据
        this.removeById(id);
        //删除客户-联系人表的数据
        customerUserService.remove(Wrappers.<CustomerUser>lambdaQuery().eq(CustomerUser::getCustomerId, id));
    }

    /**
     * 私海客户表分页（添加权限自己看自己）
     */
    @Override
    public Page<CustomerVo> privateSeaPage(CustomerSelectDto dto) {
//        LambdaQueryWrapper<Customer> wrapper = Wrappers.<Customer>lambdaQuery();
        IWrapper<CustomerVo> wrapper = IWrapper.getWrapper();
        wrapper.eq("c", Customer::getSource, dto.getSource());
        wrapper.eq("c", Customer::getStatus, dto.getStatus());
        //国家ID查询
        wrapper.eq(Customer::getCountryId, dto.getCountryId());
        //省份ID查询
        wrapper.eq(Customer::getProvinceId,dto.getProvinceId());
        //城市ID查询
        wrapper.eq(Customer::getCityId,dto.getCityId());
        //客户代码
        wrapper.like(Customer::getCustomerCode,dto.getCustomerCode());
        //客户名称
        wrapper.like(Customer::getName,dto.getName());
        //业务员查询
        wrapper.eq(Customer::getUserId,dto.getName());
        //客户标签查询（多个标签用逗号隔开）
        if(StringUtils.isNotEmpty(dto.getTag())){
            List<String> tagList = Arrays.asList(dto.getTag().split(","));
            tagList.forEach(tag->wrapper.like(Customer::getTag,tag));
        }
        //添加权限（自己看自己）
        wrapper.eq(Customer::getUserId, SecurityUtils.getUserId());

        //置顶条件
        List<Long> customerIds = customerTopService.listObject(CustomerTop::getCustomerId, q -> q.eq(CustomerTop::getUserId,
                SecurityUtils.getUserId()));
        if (ObjectUtil.isNotEmpty(customerIds)) {
            String join = StringUtils.join(customerIds, ",");
            wrapper.orderByDesc("id IN ( " + join + " )");
        }

        wrapper.orderByDesc(Customer::getCreateTime);
        Page<CustomerVo> page = baseMapper.getPage(dto.getPage(), wrapper);
        //复制城市信息
        List<CustomerVo> records = page.getRecords();
        CustomizeAreaUtil.setAreaName(records);
        //赋值客户跟进记录
        for (CustomerVo record : records) {
            List<CustomerFollowRecords> customerFollowRecordsList = customerFollowRecordsService.list(q ->
                    q.eq(CustomerFollowRecords::getCustomerId, record.getId())
                            .orderByDesc(CustomerFollowRecords::getDate).last("limit 3"));
            record.setCustomerFollowRecordsList(customerFollowRecordsList);
        }

        //赋值是否置顶
        for (CustomerVo record : records) {
            record.setIsTop(customerIds.contains(record.getId()) ? 1 : 0);
        }

        return page;
    }

    /**
     * 来源存量（客户分析）
     *
     * @param query
     * @return
     */
    @Override
    public List<CustomerVo> sourceStock(QueryWrapper<Object> query) {
        return baseMapper.sourceStock(query);
    }

    /**
     * 来源增量（客户分析）
     *
     * @param query
     * @return
     */
    @Override
    public List<CustomerVo> sourceIncrement(QueryWrapper<Object> query) {
        return baseMapper.sourceIncrement(query);
    }


    //添加客户用户表的信息
    private void saveCustomerUse(CustomerDto customerDto) {
        List<CustomerUser> customerUserDtoList = customerDto.getCustomerUserList();
        customerUserDtoList.forEach(customerUserDto -> customerUserDto.setCustomerId(customerDto.getId()));
        customerUserDtoList.forEach(customerUserDto -> customerUserDto.setId(null));//防止传id过来导致key冲突
        customerUserService.saveBatch(customerUserDtoList);
    }

    /**
     * 修改客户标签
     */
    @Override
    public void editTag(CustomerDto customerDto) {
        this.updateById(customerDto);
    }

    /**
     * 客户来源统计
     */
    @Override
    public Map<String,Object> sourceStatistics(CustomerSelectDto customerDto) {
        if (ObjectUtil.isEmpty(customerDto) && ObjectUtil.isEmpty(customerDto.getStatisticsType())){
            throw new ServiceException("参数异常：统计类型不能为null");
        }
        //存放统计数据
        Map<String,Object> map = new HashMap<>();
        QueryWrapper<Customer> query = Wrappers.query();
        if (ObjectUtil.isNotEmpty(customerDto.getType())){
            //私海客户查询
            if (customerDto.getType().equals("1")) {
                query.isNotNull("user_id");
                //私海客户需要添加权限（自己查自己）
                query.eq("user_id", SecurityUtils.getUserId());
            } else if (customerDto.getType().equals("0")) {//公海客户
                query.and(wrapper1 -> wrapper1.isNull("user_id").or().eq("user_id", ""));
            }
        }
        if (customerDto.getStatisticsType() == 1){//来源统计
            query.groupBy("source");
            query.select("count(*) count,source");
        }else if (customerDto.getStatisticsType() == 2){//数据类型统计
            query.groupBy("status");
            query.select("count(*) count,status");
        }else if (customerDto.getStatisticsType() == 3){//业务员统计
            query.groupBy("user_id");
            query.select("count(*) count,user_id");
        }
        List<Customer> customerList = baseMapper.selectList(query);


        UserUtil.assignmentNickName(customerList, Customer::getUserId,Customer::setUserName);

        Integer countAmount = customerList.stream().map(customer -> customer.getCount()).reduce(Integer::sum).orElse(0);
        map.put("countAmount",countAmount);
        map.put("customerList",customerList);
        return map;
    }

    /**
     * 客户分配
     */
    @Override
    public void customerAllocation(CustomerDto dto) {
        baseMapper.customerAllocation(dto);
    }

    // 根据字典编码获取字典的数据
    private List<DictTenantDataVo> getDict(String code) {
        DictTenantDataSelectDto dto = new DictTenantDataSelectDto();
        dto.setDictCode(code);
        List<DictTenantDataVo> dictTenantDataServiceList = dictTenantDataService.getList(dto);
        return dictTenantDataServiceList;
    }

    @Override
    public CustomerCodeAndCountryId getCustomerCodeAndCountryId(Long customerId) {
        if (customerId == null) {
            throw new ServiceException("客户id不能为空");
        }

        Customer customer = getById(customerId);
        if (customer == null) {
            throw new ServiceException("未找到客户");
        }

        CustomerCodeAndCountryId customerCodeAndCountryId = new CustomerCodeAndCountryId();
        customerCodeAndCountryId.setCountryId(customer.getCountryId());
        customerCodeAndCountryId.setCustomerCode(customer.getCode());

        return customerCodeAndCountryId;
    }
}
