package com.sunxung.factoring.service.salescontractmanagement.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.dict.impl.SalesContractPersonTypeDict;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.project.ProjectInformation;
import com.sunxung.factoring.entity.salescontractmanagement.*;
import com.sunxung.factoring.entity.salescontractmanagement.vo.SalesContractBasicVo;
import com.sunxung.factoring.entity.sys.FileStorageDO;
import com.sunxung.factoring.mapper.salescontractmanagement.CSalesContractBasicInfoMapper;
import com.sunxung.factoring.service.project.BusinessProcessingLogService;
import com.sunxung.factoring.service.project.IProjectInformationService;
import com.sunxung.factoring.service.salescontractmanagement.*;
import com.sunxung.factoring.service.sys.FileService;
import com.sunxung.factoring.service.sys.ISysAttachmentRefService;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 销售合同-基本信息表 服务实现类
 * </p>
 *
 * @author yafan
 * @since 2023-12-09
 */
@Service("sales_contract_basicService")
public class CSalesContractBasicInfoServiceImpl extends ServiceImpl<CSalesContractBasicInfoMapper, CSalesContractBasicInfo>
        implements ICSalesContractBasicInfoService {

    @Autowired
    private ISalesContractBasicInfoHistoryService salesContractBasicInfoHistoryService;
    @Autowired
    private SalesContractService salesContractService;
    @Resource(name = "projectInformationService")
    private IProjectInformationService projectInformationService;
    @Autowired
    private ISalesContractGoodsInfoHistoryService salesContractGoodsInfoHistoryService;
    @Autowired
    private ISysAttachmentRefService attachmentRefService;
    @Autowired
    private ISalesContractPersonInfoHistoryService salesContractPersonInfoHistoryService;
    @Autowired
    private ISalesContractPersonInfoService personInfoService;
    @Autowired
    private SalesContractGoodsInfoService goodsInfoService;
    @Autowired
    private FileService fileService;
    @Autowired
    private UserService userService;
    @Autowired
    private FlowableService flowableService;
    @Autowired
    private BusinessProcessingLogService businessProcessingLogService;
    @Autowired
    private SalesContractGoodsInfoService salesContractGoodsInfoService;

    @Override
    public SalesContractBasicInfoHistory getView(Long id) {

        SalesContractBasicInfoHistory history = salesContractBasicInfoHistoryService.getById(id);

        if (history != null && history.getId() != null) {


            //获取对应的销售合同管理基础信息
            SalesContractBasicVo salesContractBasicVo = salesContractService
                    .getBasicInfoById(history.getcSalesContractManagementId());
            history.setContractBasicVo(salesContractBasicVo);

            //获取人员信息
            //人员信息
            List<SalesContractPersonInfoHistory> personInfoList = salesContractPersonInfoHistoryService.lambdaQuery()
                    .eq(SalesContractPersonInfoHistory::getSalesContractBasicInfoHIsId, id).list();
            history.setPersonInfoList(personInfoList);

            //货物信息
            List<SalesContractGoodsInfoHistory> goodsInfoList = salesContractGoodsInfoHistoryService.lambdaQuery()
                    .eq(SalesContractGoodsInfoHistory::getSalesContractBasicInfoHIsId, id).list();
            history.setGoodsInfoList(goodsInfoList);

            //合同文件
            List<FileStorageDO> fileStorageDOS = fileService.findByBusinessId(id, FileModuleDict.ChildEnum.SALES_CONTRACT_HIS_FILE.getCode());
            history.setFileStorages(fileStorageDOS);


            //获取货物信息
            List<SalesContractGoodsInfoHistory> goodsInfoHistoryList = salesContractGoodsInfoHistoryService.lambdaQuery()
                    .eq(SalesContractGoodsInfoHistory::getSalesContractBasicInfoHIsId, id).list();
            history.setGoodsInfoList(goodsInfoHistoryList);
        }
        return history;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(CSalesContractBasicInfo salesContractBasicInfo) {

        ThreadLocalUtil.setUser(userService.getByLoginName("admin"));

        CSalesContract salesContractManagement = salesContractService.getById(salesContractBasicInfo.getcSalesContractManagementId());

        if (salesContractBasicInfo.getCommit() == 1) {
            if (CollectionUtil.isEmpty(salesContractBasicInfo.getPersonInfoList())) {
                throw new BusinessException(CodeUtil.FAIL, "人员信息不能为空！");
            }

            List<CSalesContractPersonInfo> salesContractPersonInfos = salesContractBasicInfo.getPersonInfoList();
            if (CollectionUtil.isNotEmpty(salesContractPersonInfos)) {
                boolean anyMatch = salesContractPersonInfos.stream().anyMatch(r -> r.getType()
                        .equals(SalesContractPersonTypeDict.ChildEnum.SALESCONTRACTPERSONTYPE_SIGN.getCode()));
                boolean anyMatch1 = salesContractPersonInfos.stream().anyMatch(r -> r.getType()
                        .equals(SalesContractPersonTypeDict.ChildEnum.SALESCONTRACTPERSONTYPE_ACCEPTANCE.getCode()));
                boolean anyMatch2 = salesContractPersonInfos.stream().anyMatch(r -> r.getType()
                        .equals(SalesContractPersonTypeDict.ChildEnum.SALESCONTRACTPERSONTYPE_SETTLEMENT.getCode()));
                if (!anyMatch || !anyMatch1 || !anyMatch2) {
                    throw new ValidatorException(CodeUtil.FAIL, "合同签署人,验收经办人,结算经办人,每种类型至少一人！");
                }
            }

            if (CollectionUtil.isEmpty(salesContractBasicInfo.getGoodsInfoList())) {
                throw new BusinessException(CodeUtil.FAIL, "货物信息不能为空！");
            }
        }


        if (salesContractBasicInfo.getId() != null) {
            //退回重新提交
            updateById(salesContractBasicInfo);

            //更新人员信息
            personInfoService.remove(new QueryWrapper<CSalesContractPersonInfo>()
                    .eq("c_sales_contract_basic_info_id", salesContractBasicInfo.getId()));

            //更新货物信息
            goodsInfoService.remove(new QueryWrapper<CSalesContractGoodsInfo>()
                    .eq("c_sales_contract_basic_info_id", salesContractBasicInfo.getId()));

            //更新合同文件
            fileService.lambdaUpdate().eq(FileStorageDO::getBusinessType, FileModuleDict.ChildEnum.SALES_CONTRACT_FILE.getCode())
                    .eq(FileStorageDO::getBusinessId, salesContractBasicInfo.getId())
                    .set(FileStorageDO::getBusinessId, null).update();

            List<Long> fileIds = salesContractBasicInfo.getFileIds();
            if (CollectionUtil.isNotEmpty(fileIds)) {
                fileIds.forEach(c -> {
                    FileStorageDO fileStorageDO = fileService.getById(c);
                    fileStorageDO.setBusinessId(salesContractBasicInfo.getId());
                    fileService.updateById(fileStorageDO);
                });
            }

        } else {
            //首次
            //保存销售合同基础信息
            save(salesContractBasicInfo);

            //保存文件信息
            fileService.updateBusinessId(salesContractBasicInfo.getFileIds(), salesContractBasicInfo.getId());
        }

        //保存人员信息
        Long basicId = salesContractBasicInfo.getId();
        if (CollectionUtil.isNotEmpty(salesContractBasicInfo.getPersonInfoList())) {
            salesContractBasicInfo.getPersonInfoList().forEach(person -> {
                person.setcSalesContractBasicInfoId(basicId);
                personInfoService.save(person);
            });
        }

        //保存货物信息
        if (CollectionUtil.isNotEmpty(salesContractBasicInfo.getGoodsInfoList())) {
            salesContractBasicInfo.getGoodsInfoList().forEach(goods -> {
                goods.setcSalesContractBasicInfoId(basicId);
                goods.setOccupy(0);
                String salesPrice = StringUtil.formatStrT(goods.getSalesPrice());
                goods.setSalesPrice(salesPrice);
                goodsInfoService.save(goods);
            });
        }

        if (salesContractBasicInfo.getCommit() == 1) {
            //提交
            //流程处理
            String processKey = ConstantUtil.SALES_CONTRACT;
            String assigneeKey = ConstantUtil.SALES_CONTRACT_APPROVAL + ConstantUtil._CANDIDATE;

            //taskId
            BusinessProcessingLog lastLog = businessProcessingLogService.getByBusinessTypeBusinessKey(processKey, salesContractManagement.getId());
            String taskId = lastLog.getHistoricTaskId();

            List<Long> legalSpecialists = userService.findUserIdByRole(ConstantUtil.LEGAL_SPECIALIST);
            if (legalSpecialists == null || legalSpecialists.size() == 0) {
                throw new ValidatorException(CodeUtil.FAIL, ConstantUtil.OPERATION_SPECIALIST + "角色内无任何用户！");
            }
            List<String> legalIds = legalSpecialists.stream().map(c -> c.toString()).collect(Collectors.toList());


            Map<String, Object> procVariables = new HashMap<>(1);
            procVariables.put(assigneeKey, legalIds);
            Map<String, Object> msgVariables = new HashMap<>(2);
            //项目信息
            ProjectInformation projectInformation = projectInformationService
                    .getOne(new QueryWrapper<ProjectInformation>()
                            .eq("business_number", salesContractManagement.getBusinessNumber()));
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, projectInformation.getProjectName());
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                    "业务编号为" + salesContractManagement.getBusinessNumber() + "”的项目已inOut“"
                            + ConstantConversionUtil.flowBusinessKeyNames.get(processKey) + "—formBusiness”阶段，");
            Long historyId = addHistory(salesContractBasicInfo);
            Boolean success = flowableService.completeMyTask(taskId, salesContractManagement, procVariables, null, historyId,
                    msgVariables, processKey, legalSpecialists);
            if (success == null || !success) {
                throw new ValidatorException(CodeUtil.FAIL, "销售合同-业务录入时出错啦！");
            }
        }

    }

    //新增历史
    private Long addHistory(CSalesContractBasicInfo salesContractBasicInfo) {
        Long oldEntityId = salesContractBasicInfo.getId();
        //添加合同信息
        SalesContractBasicInfoHistory salesContractBasicInfoHistory = new SalesContractBasicInfoHistory();
        BeanUtils.copyProperties(salesContractBasicInfo, salesContractBasicInfoHistory);
        salesContractBasicInfoHistory.setId(null);
        salesContractBasicInfoHistoryService.save(salesContractBasicInfoHistory);

        //添加货物信息
        List<CSalesContractGoodsInfo> salesContractGoodsInfoList = salesContractGoodsInfoService
                .lambdaQuery().eq(CSalesContractGoodsInfo::getcSalesContractBasicInfoId, salesContractBasicInfo.getId()).list();
        if (salesContractGoodsInfoList != null && salesContractGoodsInfoList.size() > 0) {
            for (CSalesContractGoodsInfo goodsInfo : salesContractGoodsInfoList) {
                SalesContractGoodsInfoHistory salesContractGoodsInfoHistory = new SalesContractGoodsInfoHistory();
                BeanUtils.copyProperties(goodsInfo, salesContractGoodsInfoHistory, "id");
                salesContractGoodsInfoHistory.setSalesContractBasicInfoHIsId(salesContractBasicInfoHistory.getId());
                salesContractGoodsInfoHistoryService.save(salesContractGoodsInfoHistory);
            }
        }
        //添加合同文件历史
        List<FileStorageDO> fileStorageDOS = fileService.listByIds(salesContractBasicInfo.getFileIds());
        if (CollectionUtil.isNotEmpty(fileStorageDOS)) {
            fileStorageDOS.forEach(fileStorageDO -> {
                FileStorageDO hisFile = new FileStorageDO();
                BeanUtils.copyProperties(fileStorageDO, hisFile, "id");
                hisFile.setBusinessType(FileModuleDict.ChildEnum.SALES_CONTRACT_HIS_FILE.getCode());
                hisFile.setBusinessId(salesContractBasicInfoHistory.getId());
                fileService.save(hisFile);
            });
        }
        //保存人员信息
        List<CSalesContractPersonInfo> salesContractPersonInfos = personInfoService
                .list(new QueryWrapper<CSalesContractPersonInfo>().eq("c_sales_contract_basic_info_id", salesContractBasicInfo.getId()));
        salesContractPersonInfos.forEach(r -> {
            SalesContractPersonInfoHistory salesContractPersonInfoHistory = new SalesContractPersonInfoHistory();
            BeanUtils.copyProperties(r, salesContractPersonInfoHistory, "id");
            salesContractPersonInfoHistory.setSalesContractBasicInfoHIsId(salesContractBasicInfoHistory.getId());
            salesContractPersonInfoHistoryService.save(salesContractPersonInfoHistory);
        });
        return salesContractBasicInfoHistory.getId();
    }

}
