package cn.iocoder.yudao.module.crm.service.crmindex;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAContractApi;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAReceiptApi;
import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.ContractStatisticsDTO;
import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.ReceiptStatisticsDTO;
import cn.iocoder.yudao.module.crm.controller.admin.crmindex.vo.BrieCountVO;
import cn.iocoder.yudao.module.crm.controller.admin.crmindex.vo.CrmIndexRespVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmclues.CrmCluesDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomercontacts.CrmCustomerContactsDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO;
import cn.iocoder.yudao.module.crm.dal.mysql.crmbusiness.CrmBusinessMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomercontacts.CrmCustomerContactsMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
import cn.iocoder.yudao.module.system.api.notice.NoticeApi;
import cn.iocoder.yudao.module.system.api.notice.dto.NoticeDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 商机 Service 实现类
 *
 * @author yshop
 */
@Service
@Validated
public class CrmIndexServiceImpl implements CrmIndexService {

    @Resource
    private CrmBusinessMapper businessMapper;
    @Resource
    private CrmCustomerMapper customerMapper;
    @Resource
    private CrmCluesMapper crmCluesMapper;

    @Resource
    private CrmRecordMapper crmRecordMapper;
    @Resource
    private CrmCustomerContactsMapper customerContactsMapper;
    @Resource
    private NoticeApi noticeApi;
    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private BpmOAContractApi bpmOAContractApi;

    @Resource
    private BpmOAReceiptApi receiptApi;
    @Resource
    private UserLiveTreeService userLiveTreeService;


    @Override
    public CrmIndexRespVO getIndexCount(String relation, Long userId) {
        return CrmIndexRespVO.builder()
                .brieCountVO(getBrieCount(relation, userId))
                .build();
    }

    /**
     * 统计当天
     *
     * @return
     */
    private BrieCountVO getBrieCount(String relation, Long userId) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        Date todayStart = DateUtil.beginOfDay(new Date());
        Date todayEnd = DateUtil.endOfDay(new Date());

        Date yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday());
        Date yesterdayEnd = DateUtil.endOfDay(DateUtil.yesterday());

        List<Long> ids = new ArrayList<>();
        Long adminId = SecurityFrameworkUtils.getLoginUserId();
        if (RelationEnum.MY.getValue().equals(relation)) {
            ids.add(adminId);
        } else if (RelationEnum.SUB.getValue().equals(relation)) {
            if (userId != null) {
                ids.add(userId);
            } else {
                ids = userLiveTreeService.getItemIdsByUserId(adminId);
            }
        }
        if (CollUtil.isEmpty(ids)){
            return BrieCountVO.builder().build();
        }
        Long count01 = businessMapper.selectCount(new LambdaQueryWrapper<CrmBusinessDO>()
                .in(!ids.isEmpty(), CrmBusinessDO::getOwnerUserId, ids)
                .between(CrmBusinessDO::getCreateTime, todayStart, todayEnd));
        Long count001 = businessMapper.selectCount(new LambdaQueryWrapper<CrmBusinessDO>()
                .in(!ids.isEmpty(), CrmBusinessDO::getOwnerUserId, ids)
                .between(CrmBusinessDO::getCreateTime, yesterdayStart, yesterdayEnd));
        String per001 = "0";
        if (count001 > 0) {
            per001 = NumberUtil.div(NumberUtil.sub(count01, count001), count001, 2)
                    .multiply(new BigDecimal("100")).toString();
        }

        Long count02 = crmCluesMapper.selectCount(new LambdaQueryWrapper<CrmCluesDO>()
                .in(!ids.isEmpty(), CrmCluesDO::getOwnerUserId, ids)
                .between(CrmCluesDO::getCreateTime, todayStart, todayEnd));
        Long count002 = crmCluesMapper.selectCount(new LambdaQueryWrapper<CrmCluesDO>()
                .in(!ids.isEmpty(), CrmCluesDO::getOwnerUserId, ids)
                .between(CrmCluesDO::getCreateTime, yesterdayStart, yesterdayEnd));
        String per002 = "0";
        if (count002 > 0) {
            per002 = NumberUtil.div(NumberUtil.sub(count02, count002), count002, 2)
                    .multiply(new BigDecimal("100")).toString();
        }

        Long count03 = customerMapper.selectCount(new LambdaQueryWrapper<CrmCustomerDO>()
                .in(!ids.isEmpty(), CrmCustomerDO::getOwnerUserId, ids)
                .between(CrmCustomerDO::getCreateTime, todayStart, todayEnd));
        Long count003 = customerMapper.selectCount(new LambdaQueryWrapper<CrmCustomerDO>()
                .in(!ids.isEmpty(), CrmCustomerDO::getOwnerUserId, ids)
                .between(CrmCustomerDO::getCreateTime, yesterdayStart, yesterdayEnd));
        String per003 = "0";
        if (count003 > 0) {
            per003 = NumberUtil.div(NumberUtil.sub(count03, count003), count003, 2)
                    .multiply(new BigDecimal("100")).toString();
        }

        Long count04 = crmRecordMapper.selectCount(new LambdaQueryWrapper<CrmRecordDO>()
                .in(!ids.isEmpty(), CrmRecordDO::getCreator, ids)
                .between(CrmRecordDO::getCreateTime, todayStart, todayEnd));
        Long count004 = crmRecordMapper.selectCount(new LambdaQueryWrapper<CrmRecordDO>()
                .in(!ids.isEmpty(), CrmRecordDO::getCreator, ids)
                .between(CrmRecordDO::getCreateTime, yesterdayStart, yesterdayEnd));
        String per004 = "0";
        if (count004 > 0) {
            per004 = NumberUtil.div(NumberUtil.sub(count04, count004), count004, 2)
                    .multiply(new BigDecimal("100")).toString();
        }

        // 获取今日合同新增数量
        ContractStatisticsDTO contractStatisticsDTO = bpmOAContractApi.getContractCount(relation).getCheckedData();
        // 设置今日新增数量
        Long count05 = Long.valueOf(contractStatisticsDTO.getTodayAdditions());
        // 设置昨日新增数量
        Long count005 = Long.valueOf(contractStatisticsDTO.getYesterdayAdditions());
        // 设置较昨日比率
        String per005 = contractStatisticsDTO.getCountPercentage().toString();
        // 设置今日新增金额
        BigDecimal count06 = contractStatisticsDTO.getTodayAddMoney();
        // 设置昨日新增金额
        BigDecimal count006 = contractStatisticsDTO.getYesterdayAddMoney();
        // 设置较昨日比率
        String per006 = contractStatisticsDTO.getMoneyPercentage().toString();

        // 获取今日回款新增金额
        ReceiptStatisticsDTO receiptStatisticsDTO = receiptApi.getReceiptCount(relation).getCheckedData();
        // 设置今日新增金额
        BigDecimal count07 = receiptStatisticsDTO.getTodayAddMoney();
        // 设置昨日新增金额
        BigDecimal count007 = receiptStatisticsDTO.getYesterdayAddMoney();
        // 设置较昨日比率
        String per007 = receiptStatisticsDTO.getMoneyPercentage().toString();

        Long count08 = customerContactsMapper.selectCount(new LambdaQueryWrapper<CrmCustomerContactsDO>()
                .in(!ids.isEmpty(), CrmCustomerContactsDO::getOwnerUserId, ids)
                .between(CrmCustomerContactsDO::getCreateTime, todayStart, todayEnd));
        Long count008 = customerContactsMapper.selectCount(new LambdaQueryWrapper<CrmCustomerContactsDO>()
                .in(!ids.isEmpty(), CrmCustomerContactsDO::getOwnerUserId, ids)
                .between(CrmCustomerContactsDO::getCreateTime, yesterdayStart, yesterdayEnd));
        String per008 = "0";
        if (count008 > 0) {
            per008 = NumberUtil.div(NumberUtil.sub(count08, count008), count008, 2)
                    .multiply(new BigDecimal("100")).toString();
        }

        Long count09 = customerMapper.selectCount(new LambdaQueryWrapper<CrmCustomerDO>()
                .between(CrmCustomerDO::getDealTime, todayStart, todayEnd)
                .eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_1.getValue())
                .eq(CrmCustomerDO::getCreator, loginUserId));
        Long count10 = customerMapper.selectCount(new LambdaQueryWrapper<CrmCustomerDO>()
                .between(CrmCustomerDO::getDealTime, todayStart, todayEnd)
                .eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_0.getValue())
                .eq(CrmCustomerDO::getCreator, loginUserId));
        Long count11 = businessMapper.selectCount(new LambdaQueryWrapper<CrmBusinessDO>()
                .between(CrmBusinessDO::getDealTime, todayStart, todayEnd)
                .eq(CrmBusinessDO::getIsEnd, ShopCommonEnum.IS_STATUS_1.getValue())
                .eq(CrmBusinessDO::getCreator, loginUserId));
        Long count12 = businessMapper.selectCount(new LambdaQueryWrapper<CrmBusinessDO>()
                .between(CrmBusinessDO::getDealTime, todayStart, todayEnd)
                .eq(CrmBusinessDO::getIsEnd, ShopCommonEnum.IS_STATUS_0.getValue())
                .eq(CrmBusinessDO::getCreator, loginUserId));
        Long count13 = noticeApi.count(new NoticeDTO()
                .setStatus(CommonStatusEnum.ENABLE.getStatus())
                .setBeginTime(todayStart)
                .setEndTime(todayEnd)).getCheckedData();
        return BrieCountVO.builder()
                .count01(count01).count001(count001).per001(per001)
                .count02(count02).count002(count002).per002(per002)
                .count03(count03).count003(count003).per003(per003)
                .count04(count04).count004(count004).per004(per004)
                .count05(count05).count005(count005).per005(per005)
                .count06(count06).count006(count006).per006(per006)
                .count07(count07).count007(count007).per007(per007)
                .count08(count08).count008(count008).per008(per008)
                .count09(count09)
                .count10(count10)
                .count11(count11)
                .count12(count12)
                .count13(count13)
                .build();


    }
}
