package com.dayou.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dayou.bo.SimpleParentModel;
import com.dayou.common.BaseEntity;
import com.dayou.dto.CommissionDeclareDTO;
import com.dayou.dto.SimpleDepartmentModel;
import com.dayou.dto.SimplePostModel;
import com.dayou.dto.UserShareRate;
import com.dayou.entity.*;
import com.dayou.enums.FinanceInvoiceState;
import com.dayou.enums.MainBusinessEnum;
import com.dayou.enums.UserTypeEnum;
import com.dayou.exception.ErrorCode;
import com.dayou.mapper.CommissionDeclareMapper;
import com.dayou.message.annotation.SendMessage;
import com.dayou.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayou.service.workflow.IWorkFlowNodeInstanceService;
import com.dayou.service.workflow.IWorkFlowService;
import com.dayou.service.workflow.IWorkTaskRecordService;
import com.dayou.utils.LoginContext;
import com.dayou.vo.CommissionDeclareDetailVO;
import com.dayou.vo.CommissionDeclareTodoCheckVO;
import com.dayou.vo.CommissionDeclareVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.dayou.enums.MainBusinessEnum.*;
import static com.dayou.exception.ErrorCode.PERMISSION_ERROR;
import static com.dayou.message.MessageTypeEnum.MAJOR_DECLARE_REMIND;


/**
 * <p>
 * 提成申报 服务实现类
 * </p>
 *
 * @author wucl
 * @since 2024-05-15
 */
@DS("mbs")
@Service
public class CommissionDeclareServiceImpl extends ServiceImpl<CommissionDeclareMapper, CommissionDeclare> implements ICommissionDeclareService {


    @Autowired
    private CommissionDeclareMapper commissionDeclareMapper;

    @Autowired
    private IMajorProductionAllotService majorProductionAllotService;

    @Autowired
    private IWorkFlowService workFlowService;

    @Autowired
    private IMajorProductionService majorProductionService;

    @Autowired
    private IMajorService majorService;

    @Autowired
    private IAssetsService assetsService;

    @Autowired
    private IAssetsProductionService assetsProductionService;

    @Autowired
    private IWorkFlowNodeInstanceService workFlowNodeInstanceService;

    @Autowired
    private IMessageService messageService;

    @Autowired
    private IBusinessPerformanceDistributionService iBusinessPerformanceDistributionService;

    @Autowired
    private IWorkTaskRecordService workTaskRecordService;



    @Override
    public Boolean delete(Long id){
        //逻辑删除
        return this.removeById(id);
    }

    @Override
    public Page<CommissionDeclareVO> majorMarketDeclarePage(Page page, CommissionDeclareVO commissionDeclare) {
        Long currentMarketUserId = LoginContext.getCurrentUserId();
        return commissionDeclareMapper.majorMarketDeclarePage(page,commissionDeclare,currentMarketUserId);
    }

    /**
     * 根据部门id查询大中型市场人员提成申报信息
     * @param page
     * @param commissionDeclare
     * @return
     */
    @Override
    public Page<CommissionDeclareVO> majorMarketDeclarePageByDepartment(Page page, CommissionDeclareVO commissionDeclare) {
        List<SimpleParentModel> depList = LoginContext.getLoginCacheUserBO().getDepartmentList();
        Optional<Long> dep = depList.stream()
                .filter(obj -> "市场一部".equals(obj.getName()) || "市场二部".equals(obj.getName()) || "资产评估事业部".equals(obj.getName()))
                .map(SimpleParentModel::getId)
                .findFirst();
        if (!dep.isPresent()) {
            return commissionDeclareMapper.majorMarketDeclarePageByDepartment(page, commissionDeclare, depList.get(0).getId());
        }else {
            return commissionDeclareMapper.majorMarketDeclarePageByDepartment(page, commissionDeclare, dep.get());
        }
    }

    /**
     * 根据部门id查询大中型市场人员提成申报信息导出excel
     * @param commissionDeclare
     * @return
     */
    @Override
    public List<CommissionDeclareVO> majorMarketDeclarePageByDepartmentExport(CommissionDeclareVO commissionDeclare) {
        List<SimpleParentModel> depList = LoginContext.getLoginCacheUserBO().getDepartmentList();
        Optional<Long> dep = depList.stream()
                .filter(obj -> "市场一部".equals(obj.getName()) || "市场二部".equals(obj.getName()) || "资产评估事业部".equals(obj.getName()))
                .map(SimpleParentModel::getId)
                .findFirst();
        if (!dep.isPresent()) {
            return commissionDeclareMapper.majorMarketDeclarePageByDepartmentExport(commissionDeclare, depList.get(0).getId());
        }else {
            return commissionDeclareMapper.majorMarketDeclarePageByDepartmentExport(commissionDeclare, dep.get());
        }
    }

    @Override
    public Page<CommissionDeclareVO> majorEvaluateDeclarePage(Page page, CommissionDeclareVO commissionDeclare) {
        Long currentEvaluateUserId = LoginContext.getCurrentUserId();
        return commissionDeclareMapper.majorEvaluateDeclarePage(page,commissionDeclare,currentEvaluateUserId);
    }

    /**
     * 根据部门id查询大中型提成申报信息
     * @param page
     * @param commissionDeclare
     * @return
     */
    @Override
    public Page<CommissionDeclareVO> majorEvaluateDeclarePageByDepartment(Page page, CommissionDeclareVO commissionDeclare) {
        List<SimpleParentModel> depList = LoginContext.getLoginCacheUserBO().getDepartmentList();
        Optional<Long> dep = depList.stream()
                .filter(obj -> "评估一部".equals(obj.getName()) || "评估二部".equals(obj.getName()) || "评估三部".equals(obj.getName()))
                .map(SimpleParentModel::getId)
                .findFirst();
        if (!dep.isPresent()) {
            return commissionDeclareMapper.majorEvaluateDeclarePageByDepartment(page, commissionDeclare, depList.get(0).getId());
        }else {
            return commissionDeclareMapper.majorEvaluateDeclarePageByDepartment(page, commissionDeclare, dep.get());
        }
    }

    /**
     * 根据部门id查询大中型提成申报信息导出excel
     * @param commissionDeclare
     * @return
     */
    @Override
    public List<CommissionDeclareVO> majorEvaluateDeclarePageByDepartmentExport(CommissionDeclareVO commissionDeclare) {
        List<SimpleParentModel> depList = LoginContext.getLoginCacheUserBO().getDepartmentList();
        Optional<Long> dep = depList.stream()
                .filter(obj -> "评估一部".equals(obj.getName()) || "评估二部".equals(obj.getName()) || "评估三部".equals(obj.getName()))
                .map(SimpleParentModel::getId)
                .findFirst();
        if (!dep.isPresent()) {
            return commissionDeclareMapper.majorEvaluateDeclarePageByDepartmentExport(commissionDeclare, depList.get(0).getId());
        }else {
            return commissionDeclareMapper.majorEvaluateDeclarePageByDepartmentExport(commissionDeclare, dep.get());
        }
    }

    @Override
    @SendMessage(messageType = MAJOR_DECLARE_REMIND)
    @Transactional
    public Long commissionDeclare(CommissionDeclareDTO declareDTO) {
        removeRejectDeclare(declareDTO);
        //保存申报记录
        CommissionDeclare commissionDeclare = BeanUtil.copyProperties(declareDTO, CommissionDeclare.class);
        commissionDeclare.setDeclareResult(FinanceInvoiceState.审核中.name());
        commissionDeclare.setDeclareUserId(LoginContext.getCurrentUserId());
        this.save(commissionDeclare);
        //设置提成比例
        List<UserShareRate> userShareRates = declareDTO.getUserShareRates();
        List<MajorProductionAllot> collect = userShareRates.stream().map(x -> {
            MajorProductionAllot majorProductionAllot = new MajorProductionAllot();
            majorProductionAllot.setMajorId(declareDTO.getBusinessId());
            majorProductionAllot.setMajorProductionId(declareDTO.getProductionId());
            majorProductionAllot.setUserId(x.getUserId());
            majorProductionAllot.setRatio(x.getRate());
            majorProductionAllot.setUserType(UserTypeEnum.MARKET.name());
            majorProductionAllot.setDeclareId(commissionDeclare.getId());
            return majorProductionAllot;
        }).collect(Collectors.toList());
        majorProductionAllotService.saveBatch(collect);
        //提交审核流程
        workFlowService.openingDeclare(MainBusinessEnum.valueOf(declareDTO.getBusinessType()), commissionDeclare.getId());
        return commissionDeclare.getId();
    }

    @Override
    public CommissionDeclareDetailVO detail(Long id) {
        CommissionDeclareDetailVO commissionDeclareDetailVO = new CommissionDeclareDetailVO();
        CommissionDeclareVO declare = commissionDeclareMapper.detail(id);
        BeanUtil.copyProperties(declare,commissionDeclareDetailVO);
        if (declare.getBusinessType().equals(MainBusinessEnum.MAJOR_BUSINESS.name())){
            List<MainBusinessEnum> majorDeclareEnums = Arrays.asList(COMMISSION_DECLARE_MAJOR_MARKET, COMMISSION_DECLARE_MAJOR_EVALUATE);
            List<WorkFlowNodeInstance> instances = workFlowNodeInstanceService.list(new LambdaQueryWrapper<WorkFlowNodeInstance>().eq(WorkFlowNodeInstance::getBusinessId, id)
                    .in(WorkFlowNodeInstance::getBusinessType, majorDeclareEnums));
            List<String> remarks = instances.stream().map(WorkFlowNodeInstance::getComment).collect(Collectors.toList());
            commissionDeclareDetailVO.setRemarks(remarks);
            if (declare.getBusinessId()!=null){
                Major order = majorService.getOne(new LambdaQueryWrapper<Major>().select(Major::getOrderId, Major::getName).eq(BaseEntity::getId, declare.getBusinessId()).eq(BaseEntity::getDeleted, Boolean.FALSE));
                commissionDeclareDetailVO.setOrderId(order.getOrderId());
                commissionDeclareDetailVO.setName(order.getName());
            }
            if (declare.getProductionId()!=null){
                MajorProduction production = majorProductionService.getOne(new LambdaQueryWrapper<MajorProduction>()
                        .select(MajorProduction::getReportNo, MajorProduction::getProduction, MajorProduction::getName).eq(BaseEntity::getId, declare.getProductionId())
                        .eq(BaseEntity::getDeleted, Boolean.FALSE));
                commissionDeclareDetailVO.setName(production.getName());
                commissionDeclareDetailVO.setReportNo(production.getReportNo());
                commissionDeclareDetailVO.setProduction(production.getProduction());
            }
            List<UserShareRate> rates = majorProductionAllotService.allotRateByDeclareId(id);
            if (CollectionUtils.isEmpty(rates)){
                rates = majorProductionAllotService.getXList(declare.getProductionId());
            }
            commissionDeclareDetailVO.setUserShareRates(rates);
        }

        // 获取资产申报信息
        if (declare.getBusinessType().equals(MainBusinessEnum.ASSET_BUSINESS.name())){
            List<MainBusinessEnum> assetsDeclareEnums = Arrays.asList(COMMISSION_DECLARE_ASSET_MARKET, COMMISSION_DECLARE_ASSET_EVALUATE);
            List<WorkFlowNodeInstance> instances = workFlowNodeInstanceService.list(new LambdaQueryWrapper<WorkFlowNodeInstance>().eq(WorkFlowNodeInstance::getBusinessId, id)
                    .in(WorkFlowNodeInstance::getBusinessType, assetsDeclareEnums));
            List<String> remarks = instances.stream().map(WorkFlowNodeInstance::getComment).collect(Collectors.toList());
            commissionDeclareDetailVO.setRemarks(remarks);
            if (declare.getBusinessId()!=null){
                Assets order = assetsService.getOne(new LambdaQueryWrapper<Assets>().select(Assets::getOrderId, Assets::getName).eq(BaseEntity::getId, declare.getBusinessId()).eq(BaseEntity::getDeleted, Boolean.FALSE));
                commissionDeclareDetailVO.setOrderId(order.getOrderId());
                commissionDeclareDetailVO.setName(order.getName());
            }
            if (declare.getProductionId()!=null){
                AssetsProduction production = assetsProductionService.getOne(new LambdaQueryWrapper<AssetsProduction>()
                        .select(AssetsProduction::getProductionNo, AssetsProduction::getProductionType).eq(BaseEntity::getId, declare.getProductionId())
                        .eq(BaseEntity::getDeleted, Boolean.FALSE));
                commissionDeclareDetailVO.setReportNo(production.getProductionNo());
                commissionDeclareDetailVO.setProduction(production.getProductionType());
            }
            List<UserShareRate> rates = iBusinessPerformanceDistributionService.alloAssetsDistributionDeclareId(id);
            commissionDeclareDetailVO.setUserShareRates(rates);
        }

        return commissionDeclareDetailVO;
    }

    @Override
    public Page<CommissionDeclareTodoCheckVO> todoCheckPage(Page page, CommissionDeclareTodoCheckVO checkVO) {
        checkVO.setHandlerId(LoginContext.getCurrentUserId());
        Page<CommissionDeclareTodoCheckVO> ret = commissionDeclareMapper.todoCheckPage(page,checkVO);
        return ret;
    }

    @Override
    public List<CommissionDeclareTodoCheckVO> todoCheckList() {
        CommissionDeclareTodoCheckVO checkVO = new CommissionDeclareTodoCheckVO();
        checkVO.setHandlerId(LoginContext.getCurrentUserId());
        List<CommissionDeclareTodoCheckVO> list = commissionDeclareMapper.todoCheckList(checkVO);
        return list;
    }

    /**
     * 更新大中型绩效申报
     * @param declareDTO dto
     * @return Boolean
     */
    @Override
    public Boolean updateMajorCommissionDeclare(CommissionDeclareDTO declareDTO) {
        if (workTaskRecordService.detail(declareDTO.getRecordId()).getHandlerId().equals(LoginContext.getCurrentUserId())){
            return commissionDeclareMapper.updateMajorCommissionDeclare(declareDTO);
        }else{
            ErrorCode.throwBusinessException(PERMISSION_ERROR);
        }
        return null;
    }

    /**
     * 获取资产评估人员提成申报列表
     * @param page 分页参数
     * @param commissionDeclare 查询参数
     * @return Page<CommissionDeclareVO>
     */
    @Override
    public Page<CommissionDeclareVO> assetsEvaluateDeclarePage(Page page, CommissionDeclareVO commissionDeclare) {
        Long currentEvaluateUserId = LoginContext.getCurrentUserId();
        return commissionDeclareMapper.assetsEvaluateDeclarePage(page, commissionDeclare, currentEvaluateUserId);
    }

    /**
     * 资产业务新增绩效分配申报
     * @param declareDTO dto
     * @return Long
     */
    @Override
    @Transactional
    public Long assetsCommissionDeclare(CommissionDeclareDTO declareDTO) {
        removeRejectDeclare(declareDTO);
        //保存申报记录
        CommissionDeclare commissionDeclare = BeanUtil.copyProperties(declareDTO, CommissionDeclare.class);
        commissionDeclare.setDeclareResult(FinanceInvoiceState.审核中.name());
        commissionDeclare.setDeclareUserId(LoginContext.getCurrentUserId());
        this.save(commissionDeclare);

        //设置提成比例
        List<BusinessPerformanceDistribution> performanceDistributionList = new ArrayList<>();

        // 将前端传递的数据进行处理,添加成单个的对象
        for (BusinessPerformanceDistribution distribution : declareDTO.getDistributionDto().getDistributionList()){
            BusinessPerformanceDistribution performanceDistribution = new BusinessPerformanceDistribution();
            performanceDistribution.setBusinessId(declareDTO.getDistributionDto().getBusinessId());
            performanceDistribution.setBusinessType(declareDTO.getDistributionDto().getBusinessType());
            performanceDistribution.setReportNo(declareDTO.getDistributionDto().getReportNo());
            performanceDistribution.setMemberId(distribution.getMemberId());
            performanceDistribution.setPerformanceDistribution(distribution.getPerformanceDistribution());
            performanceDistribution.setMemberType(distribution.getMemberType());
            performanceDistribution.setDeclareId(commissionDeclare.getId());
            performanceDistribution.setUserType(declareDTO.getDistributionDto().getUserType());
            performanceDistribution.setParticipationDuration(distribution.getParticipationDuration());
            performanceDistributionList.add(performanceDistribution);
        }
        iBusinessPerformanceDistributionService.saveBatch(performanceDistributionList);
        //提交审核流程
        workFlowService.openingDeclare(MainBusinessEnum.valueOf(declareDTO.getBusinessType()), commissionDeclare.getId());
        return commissionDeclare.getId();
    }

    /**
     * 获取资产评估人员提成申报列表
     * @param page 分页参数
     * @param commissionDeclare 查询参数
     * @return Page<CommissionDeclareVO>
     */
    @Override
    public Page<CommissionDeclareVO> assetsMarketDeclarePage(Page page, CommissionDeclareVO commissionDeclare) {
        Long currentMarketUserId = LoginContext.getCurrentUserId();
        return commissionDeclareMapper.assetsMarketDeclarePage(page, commissionDeclare, currentMarketUserId);
    }

    /**
     * 资产待办绩效申报列表
     * @param page 分页参数
     * @param checkVO 查询参数
     * @return Page<CommissionDeclareTodoCheckVO>
     */
    @Override
    public Page<CommissionDeclareTodoCheckVO> assetsTodoCheckPage(Page page, CommissionDeclareTodoCheckVO checkVO) {
        checkVO.setHandlerId(LoginContext.getCurrentUserId());
        return commissionDeclareMapper.assetsTodoCheckPage(page,checkVO);
    }

    /**
     * 资产待办绩效申报集合
     * @return List<CommissionDeclareTodoCheckVO>
     */
    @Override
    public List<CommissionDeclareTodoCheckVO> assetsTodoCheckList() {
        CommissionDeclareTodoCheckVO checkVO = new CommissionDeclareTodoCheckVO();
        checkVO.setHandlerId(LoginContext.getCurrentUserId());
        return commissionDeclareMapper.assetsTodoCheckList(checkVO);
    }

    /**
     * 更新资产绩效申报提成比列与下限信息
     * @param declareDTO dto
     * @return Boolean
     */
    @Override
    public Boolean updateAssetsCommissionDeclare(CommissionDeclareDTO declareDTO) {
        if (workTaskRecordService.detail(declareDTO.getRecordId()).getHandlerId().equals(LoginContext.getCurrentUserId())){
            return commissionDeclareMapper.updateAssetsCommissionDeclare(declareDTO);
        }else{
             ErrorCode.throwBusinessException(PERMISSION_ERROR);
        }
        return null;
    }

    /**
     * 删除之前被拒绝的申报
     * @param declareDTO
     */
    private void removeRejectDeclare(CommissionDeclareDTO declareDTO){
        //删除申报记录
        Long businessId = declareDTO.getBusinessId();
        Long productionId = declareDTO.getProductionId();
        CommissionDeclare commissionDeclare = null;
        if (businessId!=null && productionId!=null){
            commissionDeclare = this.getOne(new LambdaQueryWrapper<CommissionDeclare>().eq(CommissionDeclare::getBusinessId, businessId)
                    .eq(CommissionDeclare::getProductionId, productionId).eq(CommissionDeclare::getBusinessType,declareDTO.getBusinessType())
                    .eq(CommissionDeclare::getDeclareUserId,LoginContext.getCurrentUserId()));
        }
        if (businessId!=null && productionId==null){
            commissionDeclare = this.getOne(new LambdaQueryWrapper<CommissionDeclare>().eq(CommissionDeclare::getBusinessId, businessId)
                    .isNull(CommissionDeclare::getProductionId).eq(CommissionDeclare::getBusinessType,declareDTO.getBusinessType())
                    .eq(CommissionDeclare::getDeclareUserId,LoginContext.getCurrentUserId()));
        }
        if (commissionDeclare!=null){
            this.delete(commissionDeclare.getId());
        }

    }
}
