package com.fjhx.sale.flow;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.fjhx.area.utils.CustomizeAreaUtil;
import com.fjhx.common.enums.CodingRuleEnum;
import com.fjhx.common.enums.FlowStatusEnum1;
import com.fjhx.common.service.coding.CodingRuleService;
import com.fjhx.common.utils.Assert;
import com.fjhx.file.utils.ObsFileUtil;
import com.fjhx.flow.core.FlowDelegate;
import com.fjhx.flow.enums.FlowStatusEnum;
import com.fjhx.sale.entity.contract.dto.ContractDto;
import com.fjhx.sale.entity.contract.dto.ContractProductDto;
import com.fjhx.sale.entity.contract.po.Contract;
import com.fjhx.sale.entity.contract.po.ContractProduct;
import com.fjhx.sale.entity.contract.po.ContractProductBom;
import com.fjhx.sale.entity.contract.po.ContractProject;
import com.fjhx.sale.service.contract.ContractProductBomService;
import com.fjhx.sale.service.contract.ContractProductService;
import com.fjhx.sale.service.contract.ContractProjectService;
import com.fjhx.sale.service.contract.ContractService;
import com.ruoyi.common.annotation.LogicIgnore;
import com.ruoyi.common.core.domain.BasePo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 外销合同流程
 *
 * @Author:caozj
 * @DATE:2023/4/3 17:38
 */
@Component
public class ContractFlow extends FlowDelegate {

    @Autowired
    private CodingRuleService codingRuleService;
    @Autowired
    private ContractService contractService;
    @Autowired
    private ContractProductService contractProductService;
    @Autowired
    private ContractProjectService contractProjectService;
    @Autowired
    private ContractProductBomService contractProductBomService;

    @Override
    public String getFlowKey() {
        return "contract_flow";
    }

    /**
     * 发起流程
     *
     * @param flowId     流程ID
     * @param submitData 采购付款数据
     * @return 业务id
     */
    @Override
    public Long start(Long flowId, JSONObject submitData) {
        ContractDto contract = submitData.toJavaObject(ContractDto.class);

        contract.setFlowId(flowId);

        if (StringUtils.isEmpty(contract.getCurrency())) {
            throw new ServiceException("币种不能为空");
        }
        contract.setCode(codingRuleService.createCode(CodingRuleEnum.CONTRACT.getKey(), contract.getBuyCorporationId()));

        // 保存合同产品
        List<ContractProductDto> contractProductList = contract.getContractProductList();

        // 赋值待处理数量
        if (CollectionUtils.isNotEmpty(contractProductList)) {
            contractProductList.forEach(item -> item.setExpendQuantity(item.getQuantity()));
        }

        //将code赋值给流程引擎
        submitData.put("code", contract.getCode());

        return start(contract);
    }

    /**
     * 结束流程
     *
     * @param flowId     流程ID
     * @param businessId 业务ID
     * @param submitData 数据
     */
    @Override
    public void end(Long flowId, Long businessId, JSONObject submitData) {
        // 通过业务ID查询合同数据
        Contract contract = contractService.getById(businessId);

        if (ObjectUtils.isEmpty(contract)) {
            throw new ServiceException("合同不存在");
        }
        // 修改合同状态为审批通过
        contract.setStatus(FlowStatusEnum1.PASS.getKey());
        contract.setApprovedDate(new Date());
        contractService.updateById(contract);
    }

    public Long start(ContractDto contract) {
        //生产公司信息校验
        Assert.notEmpty(contract.getCompanyId(), "生产公司id不能为空！");
        //销售部门id
        contract.setDeptId(SecurityUtils.getDeptId());

        // 赋值城市省份信息
        CustomizeAreaUtil.setAreaId(contract);
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        contract.setUserName(loginUser.getNickName());
        contract.setBuyCityId(contract.getCityId());
        contract.setBuyCountryId(contract.getCountryId());
        contract.setBuyProvinceId(contract.getProvinceId());
        contract.setStatus(FlowStatusEnum1.UNDER_REVIEW.getKey());

        contractService.saveOrUpdate(contract);

        // 保存合同产品
        List<ContractProductDto> contractProductListDto = contract.getContractProductList();
        contractProductListDto = ObjectUtil.isEmpty(contractProductListDto) ? new ArrayList<>() : contractProductListDto;
        for (ContractProductDto cp : contractProductListDto) {
            //对新数据创建id
            cp.setId(ObjectUtil.isEmpty(cp.getId()) ? IdWorker.getId() : cp.getId());
            //赋值合同Id
            cp.setContractId(contract.getId());
            //保存设计稿图
            ObsFileUtil.editFile(cp.getFileList(), cp.getId());
            //保存生产源文件
            ObsFileUtil.copyFileAndSave(cp.getProdFileList(), cp.getId(), 1);

            //赋值产品BOM信息
            List<ContractProductBom> contractProductBomList = cp.getContractProductBomList();
            for (ContractProductBom contractProductBom : contractProductBomList) {
                contractProductBom.setContractId(contract.getId());
                contractProductBom.setContractProductId(cp.getId());
                contractProductBom.setProductId(cp.getProductId());
            }

            contractProductBomService.editLinked(contractProductBomList, ContractProductBom::getContractProductId, cp.getId());
        }

        List<ContractProduct> contractProductList1 = BeanUtil.copyToList(contractProductListDto, ContractProduct.class);
        contractProductService.editLinked(contractProductList1, ContractProduct::getContractId, contract.getId());

        // 保存收费项目
        List<ContractProject> contractProjectList = contract.getContractProjectList();
        contractProjectList = ObjectUtil.isEmpty(contractProjectList) ? new ArrayList<>() : contractProjectList;
        for (ContractProject c : contractProjectList) {
            c.setContractId(contract.getId());
        }
        contractProjectService.editLinked(contractProjectList, ContractProject::getContractId, contract.getId());

        return contract.getId();
    }

    /**
     * 重新发起
     *
     * @param flowId
     * @param businessId
     * @param flowStatus
     * @param submitData
     */
    @Override
    @LogicIgnore
    public void relaunch(Long flowId, Long businessId, FlowStatusEnum flowStatus, JSONObject submitData) {
        //删除采购合同
        ContractDto contractDto = submitData.toJavaObject(ContractDto.class);
        if (ObjectUtils.isEmpty(contractDto)) {
            throw new ServiceException("合同数据不能为空");
        }
        start(contractDto);
    }

    /**
     * 驳回
     *
     * @param flowId
     * @param businessId
     * @param flowStatus
     */
    @Override
    public void reject(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
        contractService.update(q -> q
                .eq(Contract::getId, businessId)
                .set(Contract::getStatus, 20)//20为驳回
                .set(Contract::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );

    }

    @Override
    public void cancellation(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
        super.cancellation(flowId, businessId, flowStatus);


        contractService.update(q -> q
                .eq(Contract::getId, businessId)
                .set(Contract::getStatus, FlowStatusEnum1.CANCELLATION.getKey())
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );


    }

}
