package com.fjhx.form.service.employee.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.customer.entity.customer.po.Customer;
import com.fjhx.customer.service.customer.CustomerService;
import com.fjhx.flow.entity.flow.po.FlowExample;
import com.fjhx.flow.service.flow.FlowExampleService;
import com.fjhx.form.entity.dto.EmployeeAnalysisDto;
import com.fjhx.form.mapper.employee.EmployeeAnalysisMapper;
import com.fjhx.form.service.employee.EmployeeAnalysisService;
import com.fjhx.item.entity.product.po.ProductInfo;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.purchase.entity.pay.po.Pay;
import com.fjhx.purchase.entity.purchase.po.Purchase;
import com.fjhx.purchase.entity.subscribe.po.SubscribeDetail;
import com.fjhx.purchase.service.pay.PayService;
import com.fjhx.purchase.service.purchase.PurchaseService;
import com.fjhx.purchase.service.subscribe.SubscribeDetailService;
import com.fjhx.sale.entity.contract.po.Contract;
import com.fjhx.sale.entity.contract.po.ContractProduct;
import com.fjhx.sale.entity.documents.po.Documents;
import com.fjhx.sale.entity.sale.po.SaleQuotation;
import com.fjhx.sale.service.contract.ContractProductService;
import com.fjhx.sale.service.contract.ContractService;
import com.fjhx.sale.service.documents.DocumentsService;
import com.fjhx.sale.service.sale.SaleQuotationService;
import com.ruoyi.common.utils.wrapper.IWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EmployeeAnalysisServiceImpl implements EmployeeAnalysisService {

    @Autowired
    private CustomerService customerService;
    @Autowired
    private SaleQuotationService saleQuotationService;
    @Autowired
    private ContractService contractService;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private EmployeeAnalysisMapper employeeAnalysisMapper;
    @Autowired
    private FlowExampleService flowExampleService;
    @Autowired
    private DocumentsService documentsService;
    @Autowired
    private PurchaseService purchaseService;
    @Autowired
    private PayService payService;
    @Autowired
    private ContractProductService contractProductService;
    @Autowired
    private SubscribeDetailService subscribeDetailService;

    /**
     * 员工分析
     *
     * @return
     */
    @Override
    public Map<String, Object> info(EmployeeAnalysisDto dto) {
        //客户情况
        Map<String, Object> customerSituation = getCustomerSituation(dto);
        //产品情况
        Map<String, Object> productSituation = getProductSituation(dto);
        //往来邮件
        Map<String, Object> commEmail = getCommEmail(dto);
        //流程统计
        Map<String, Object> flowStatistics = getFlowStatistics(dto);
        //销售行为（存量客户）
        Map<String, Object> saleSituation = getSaleSituation(dto);
        //销售行为（增量客户）
        Map<String, Object> saleAddSituation = getSaleAddSituation(dto);
        //采购行为
        Map<String, Object> purchaseStatistics = getPurchaseStatistics(dto);

        //返回数据
        Map<String, Object> data = new HashMap<>();
        data.put("customerSituation", customerSituation);//客户情况
        data.put("productSituation", productSituation);//产品情况
        data.put("commMail", commEmail);//往来邮件
        data.put("flowStatistics", flowStatistics);//流程统计
        data.put("saleSituation", saleSituation);//销售行为新增统计
        data.put("saleAddSituation", saleAddSituation);//销售行为新增统计
        data.put("purchaseStatistics", purchaseStatistics);//采购行为统计
        return data;
    }

    /**
     * 客户情况
     */
    private Map<String, Object> getCustomerSituation(EmployeeAnalysisDto dto) {
        Map<String, Object> customerSituation = new HashMap<>();
        //客户存量
        long customerCount = customerService.count(q -> q
                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), Customer::getCreateTime, dto.getBeginTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Customer::getUserId, dto.getUserIds())
        );
        //客户新增
        long customerAddCount = customerService.count(q -> q
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Customer::getCreateTime, dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Customer::getCreateTime, dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Customer::getCreateUser, dto.getUserIds())
        );
        //报价单(客户数量)
        List<SaleQuotation> saleQuotationList = saleQuotationService.list(q -> q
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), SaleQuotation::getCreateTime, dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), SaleQuotation::getCreateTime, dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), SaleQuotation::getCreateUser, dto.getUserIds())
                .groupBy(SaleQuotation::getBuyCorporationId)
        );
        int saleQuotationCustomerCount = saleQuotationList.size();
        //成交合同(客户数量)
        List<Contract> contractList = contractService.list(q -> q
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Contract::getCreateTime, dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Contract::getCreateTime, dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Contract::getCreateUser, dto.getUserIds())
                .groupBy(Contract::getBuyCorporationId)
        );
        int contractCustomerCount = contractList.size();
        customerSituation.put("customerCount", customerCount);
        customerSituation.put("customerAddCount", customerAddCount);
        customerSituation.put("saleQuotationCustomerCount", saleQuotationCustomerCount);
        customerSituation.put("contractCustomerCount", contractCustomerCount);
        return customerSituation;
    }

    /**
     * 产品情况
     */
    private Map<String, Object> getProductSituation(EmployeeAnalysisDto dto) {
        Map<String, Object> productSituation = new HashMap<>();
        //产品存量
        long productCount = productInfoService.count(q -> q
                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), ProductInfo::getCreateTime, dto.getBeginTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), ProductInfo::getCreateUser, dto.getUserIds())
        );
        //产品添加
        long productAddCount = productInfoService.count(q -> q
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), ProductInfo::getCreateTime, dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), ProductInfo::getCreateTime, dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), ProductInfo::getCreateUser, dto.getUserIds())
        );
        productSituation.put("productCount", productCount);
        productSituation.put("productAddCount", productAddCount);
        return productSituation;
    }

    /**
     * 往来邮件
     */
    private Map<String, Object> getCommEmail(EmployeeAnalysisDto dto) {
        Map<String, Object> commEmail = new HashMap<>();
        DynamicDataSourceContextHolder.push(SourceConstant.MAIL);
        //获取发件数
        BigDecimal sentMailCount = employeeAnalysisMapper.getMail(IWrapper.getWrapper()
                .eq("t1.folder_name", "Sent Messages")
                .in("t2.user_id", dto.getUserIds())
        );
        //获取收件数
        BigDecimal receiveMailCount = employeeAnalysisMapper.getMail(IWrapper.getWrapper()
                .ne("t1.folder_name", "Sent Messages")
                .in("t2.user_id", dto.getUserIds())
        );
        DynamicDataSourceContextHolder.poll();
        commEmail.put("sentMailCount", sentMailCount);
        commEmail.put("receiveMailCount", receiveMailCount);
        return commEmail;
    }

    /**
     * 流程统计
     */
    private Map<String, Object> getFlowStatistics(EmployeeAnalysisDto dto) {
        Map<String, Object> flowStatistics = new HashMap<>();
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
        long flowExampleCount = flowExampleService.count(q -> q
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), FlowExample::getCreateTime, dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), FlowExample::getCreateTime, dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), FlowExample::getCreateUser, dto.getUserIds())
        );
        long waitFlowExampleCount = flowExampleService.count(q -> q
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), FlowExample::getHandleUserId, dto.getUserIds())
                .eq(FlowExample::getStatus, 1)
        );
        DynamicDataSourceContextHolder.poll();
        flowStatistics.put("flowExampleCount", flowExampleCount);
        flowStatistics.put("waitFlowExampleCount", waitFlowExampleCount);
        return flowStatistics;
    }

    /**
     * 销售行为（存量客户）
     */
    private Map<String, Object> getSaleSituation(EmployeeAnalysisDto dto) {
        Map<String, Object> saleAddSituation = new HashMap<>();
        //报价统计（报价单）
        DynamicDataSourceContextHolder.push(SourceConstant.SALE);
        Map<String, Object> quotationAddStatistics = employeeAnalysisMapper.getQuotationStatistics(IWrapper.getWrapper()
                .eq("status", 30)
                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), "sq.create_time", dto.getBeginTime())
        );
        //成交统计（销售合同）
        Map<String, Object> contractAddStatistics = employeeAnalysisMapper.getContractStatistics(IWrapper.getWrapper()
                .eq("status", 30)
                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
        );
        //到账统计（到账认领）
        Map<String, Object> claimAddStatistics = employeeAnalysisMapper.getClaimStatistics(IWrapper.getWrapper()
                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "c2.user_id", dto.getUserIds())
        );
        DynamicDataSourceContextHolder.poll();
        //单证数统计
        long documentsCount = documentsService.count(q -> q
                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), Documents::getCreateTime, dto.getBeginTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Documents::getCreateUser, dto.getUserIds()));

        saleAddSituation.put("quotationAddStatistics", quotationAddStatistics);
        saleAddSituation.put("contractAddStatistics", contractAddStatistics);
        saleAddSituation.put("claimAddStatistics", claimAddStatistics);
        saleAddSituation.put("documentsCount", documentsCount);

        return saleAddSituation;
    }

    /**
     * 销售行为（增量客户）
     */
    private Map<String, Object> getSaleAddSituation(EmployeeAnalysisDto dto) {
        Map<String, Object> saleAddSituation = new HashMap<>();
        //报价统计（报价单）
        DynamicDataSourceContextHolder.push(SourceConstant.SALE);
        Map<String, Object> quotationAddStatistics = employeeAnalysisMapper.getQuotationStatistics(IWrapper.getWrapper()
                .eq("status", 30)
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "sq.create_time", dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "sq.create_time", dto.getEndTime())
        );
        //成交统计（销售合同）
        Map<String, Object> contractAddStatistics = employeeAnalysisMapper.getContractStatistics(IWrapper.getWrapper()
                .eq("status", 30)
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "c.create_time", dto.getEndTime())
        );
        //到账统计（到账认领）
        Map<String, Object> claimAddStatistics = employeeAnalysisMapper.getClaimStatistics(IWrapper.getWrapper()
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "c.create_time", dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "c2.user_id", dto.getUserIds())
        );
        DynamicDataSourceContextHolder.poll();
        //单证数统计
        long documentsCount = documentsService.count(q -> q
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Documents::getCreateTime, dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Documents::getCreateTime, dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Documents::getCreateUser, dto.getUserIds()));

        saleAddSituation.put("quotationAddStatistics", quotationAddStatistics);
        saleAddSituation.put("contractAddStatistics", contractAddStatistics);
        saleAddSituation.put("claimAddStatistics", claimAddStatistics);
        saleAddSituation.put("documentsCount", documentsCount);

        return saleAddSituation;
    }

    /**
     * 采购行为统计
     */
    private Map<String, Object> getPurchaseStatistics(EmployeeAnalysisDto dto) {
        //待采购
        Map<String, Object> waitPurchaseStatistics = new HashMap<>();
        long contractProductCount = contractProductService.count(q -> q.gt(ContractProduct::getExpendQuantity, 0));
        long subscribeDetailCount = subscribeDetailService.count(q -> q.eq(SubscribeDetail::getStatus, 15));
        waitPurchaseStatistics.put("contractProductCount", contractProductCount);
        waitPurchaseStatistics.put("subscribeDetailCount", subscribeDetailCount);
        //采购订单
        Map<String, Object> purchaseOrder = new HashMap<>();
        //采购订单数
        long purchaseCount = purchaseService.count(q -> q
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Purchase::getCreateTime, dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Purchase::getCreateTime, dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Purchase::getCreateUser, dto.getUserIds())
        );

        DynamicDataSourceContextHolder.push(SourceConstant.PURCHASE);
        //采购金额
        BigDecimal purchaseAmount = employeeAnalysisMapper.getPurchaseAmount(IWrapper.getWrapper()
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "p.create_time", dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "p.create_time", dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "p.create_user", dto.getUserIds())
        );
        DynamicDataSourceContextHolder.poll();
        //采购付款金额
        BigDecimal purchasePayAmount = payService.getPurchasePayAmount(IWrapper.<Pay>getWrapper()
                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "pay.create_time", dto.getBeginTime())
                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "pay.create_time", dto.getEndTime())
                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "pay.create_user", dto.getUserIds()));
        purchaseOrder.put("purchaseCount", purchaseCount);
        purchaseOrder.put("purchaseAmount", purchaseAmount);
        purchaseOrder.put("purchasePayAmount", purchasePayAmount);
        //返回数据
        Map<String, Object> purchaseStatistics = new HashMap<>();
        purchaseStatistics.put("purchaseOrder", purchaseOrder);
        purchaseStatistics.put("waitPurchaseStatistics", waitPurchaseStatistics);
        return purchaseStatistics;
    }

}
