package com.sckw.contract.dubbo;

import com.sckw.contract.api.RemoteContractService;
import com.sckw.contract.api.model.dto.res.ContractCommonInfoResDto;
import com.sckw.contract.api.model.dto.res.EntInfo;
import com.sckw.contract.dao.KwcContractLogisticsMapper;
import com.sckw.contract.dao.KwcContractTradeMapper;
import com.sckw.contract.model.dto.res.QueryContractValidCountResDto;
import com.sckw.contract.model.entity.KwcContractLogistics;
import com.sckw.contract.model.entity.KwcContractLogisticsUnit;
import com.sckw.contract.model.entity.KwcContractTrade;
import com.sckw.contract.service.KwcContractLogisticsUnitService;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.ContractStatusEnum;
import com.sckw.core.model.enums.SigningWayEnum;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author czh
 * @desc 合同远程接口实现
 * @date 2023/7/31
 */
@DubboService(group = "design", version = "1.0.0")
public class RemoteContractServiceImpl implements RemoteContractService {

    @Autowired
    private KwcContractLogisticsMapper kwcContractLogisticsMapper;

    @Autowired
    private KwcContractLogisticsUnitService kwcContractLogisticsUnitService;

    @Autowired
    private KwcContractTradeMapper kwcContractTradeMapper;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    @Override
    public Map<Long, ContractCommonInfoResDto> queryContractBaseInfo(List<Long> contractIds) {
        HashMap<Long, ContractCommonInfoResDto> map = new HashMap<>(4);
        for (Long contractId : contractIds) {
            KwcContractLogistics kwcContractLogistics = kwcContractLogisticsMapper.selectById(contractId);
            if (Objects.nonNull(kwcContractLogistics)) {
                Integer status = kwcContractLogistics.getStatus();
                Integer delFlag = kwcContractLogistics.getDelFlag();
                if (Objects.equals(status, ContractStatusEnum.SAVE.getCode()) || delFlag.equals(Global.YES)) {
                    continue;
                }
                map.put(contractId, fillContractLogistics(kwcContractLogistics));
                continue;
            }

            KwcContractTrade kwcContractTrade = kwcContractTradeMapper.selectById(contractId);
            if (Objects.nonNull(kwcContractTrade)) {
                Integer status = kwcContractTrade.getStatus();
                Integer delFlag = kwcContractTrade.getDelFlag();
                if (Objects.equals(status, ContractStatusEnum.SAVE.getCode()) || delFlag.equals(Global.YES)) {
                    continue;
                }
                map.put(contractId, fillContractTrade(kwcContractTrade));
            }
        }
        return map;
    }


    /**
     * @param contractId 合同id  performedAmount履约量
     * @desc: 更新已履约量
     * @author: czh
     * @date: 2023/8/31
     */
    @Override
    public void updatePerformed(Long contractId, BigDecimal performedAmount) {
        KwcContractLogistics kwcContractLogistics = kwcContractLogisticsMapper.selectById(contractId);
        if (Objects.nonNull(kwcContractLogistics)) {
            if (kwcContractLogistics.getStatus().equals(ContractStatusEnum.COMPLETE.getCode())) {
                return;
            }
            kwcContractLogistics.setPerformedAmount(kwcContractLogistics.getPerformedAmount().add(performedAmount));
            kwcContractLogisticsMapper.updateById(kwcContractLogistics);
            return;
        }

        KwcContractTrade kwcContractTrade = kwcContractTradeMapper.selectById(contractId);
        if (Objects.nonNull(kwcContractTrade)) {
            if (kwcContractTrade.getStatus().equals(ContractStatusEnum.COMPLETE.getCode())) {
                return;
            }
            kwcContractTrade.setPerformedAmount(kwcContractTrade.getPerformedAmount().add(performedAmount));
            kwcContractTradeMapper.updateById(kwcContractTrade);
        }
    }


    /**
     * @param entId 企业id
     * @return Map<Integer, Integer>
     * @desc: 根据企业id统计企业下的有效合同个数
     * @author: czh
     * @date: 2023/9/8
     */
    @Override
    public Map<Integer, Integer> queryContractValidCount(Long entId) {
        List<Long> entIdList = new ArrayList<>();
        if (Objects.nonNull(entId)) {
            EntCacheResDto entCacheResDto = remoteSystemService.queryEntTreeById(entId);
            if (Objects.isNull(entCacheResDto)) {
                return Collections.emptyMap();
            }
            entIdList.add(entId);
            List<EntCacheResDto> child = entCacheResDto.getChild();
            if (CollectionUtils.isNotEmpty(child)) {
                entIdList.addAll(child.stream().map(EntCacheResDto::getId).toList());
            }
        }

        List<QueryContractValidCountResDto> queryContractValidCountResDtos = kwcContractTradeMapper.queryContractValidCount(entIdList);
        if (CollectionUtils.isEmpty(queryContractValidCountResDtos)) {
            return Collections.emptyMap();
        }

        return queryContractValidCountResDtos.stream().collect(Collectors.toMap(QueryContractValidCountResDto::getUnitType, QueryContractValidCountResDto::getCnt, (o, n) -> n));
    }

    private ContractCommonInfoResDto fillContractLogistics(KwcContractLogistics kwcContractLogistics) {
        ContractCommonInfoResDto contractCommonInfoResDto = new ContractCommonInfoResDto();
        List<EntInfo> entList = new ArrayList<>();
        contractCommonInfoResDto.setId(kwcContractLogistics.getId());
        contractCommonInfoResDto.setContactName(kwcContractLogistics.getName());
        contractCommonInfoResDto.setContractCode(kwcContractLogistics.getContractNo());
        contractCommonInfoResDto.setSigningWay(kwcContractLogistics.getSigningWay());
        contractCommonInfoResDto.setSigningWayName(Objects.requireNonNull(SigningWayEnum.getName(kwcContractLogistics.getSigningWay())).getName());
        contractCommonInfoResDto.setEntInfoList(entList);
        contractCommonInfoResDto.setStatus(kwcContractLogistics.getStatus());
        contractCommonInfoResDto.setStatusName(Objects.requireNonNull(ContractStatusEnum.getName(kwcContractLogistics.getStatus())).getName());
        List<KwcContractLogisticsUnit> kwcContractLogisticsUnits = kwcContractLogisticsUnitService.queryByContractId(kwcContractLogistics.getId());
        if (CollectionUtils.isNotEmpty(kwcContractLogisticsUnits)) {
            for (KwcContractLogisticsUnit kwcContractLogisticsUnit : kwcContractLogisticsUnits) {
                EntInfo entInfo = new EntInfo();
                entInfo.setEntId(kwcContractLogisticsUnit.getEntId());
                entInfo.setEntName(kwcContractLogisticsUnit.getFirmName());
                entList.add(entInfo);
            }
        }
        return contractCommonInfoResDto;
    }


    private ContractCommonInfoResDto fillContractTrade(KwcContractTrade kwcContractTrade) {
        List<EntInfo> entList = new ArrayList<>();
        ContractCommonInfoResDto contractCommonInfoResDto = new ContractCommonInfoResDto();
        contractCommonInfoResDto.setId(kwcContractTrade.getId());
        contractCommonInfoResDto.setContactName(kwcContractTrade.getName());
        contractCommonInfoResDto.setContractCode(kwcContractTrade.getContractNo());
        contractCommonInfoResDto.setSigningWay(kwcContractTrade.getSigningWay());
        contractCommonInfoResDto.setSigningWayName(Objects.requireNonNull(SigningWayEnum.getName(kwcContractTrade.getSigningWay())).getName());
        contractCommonInfoResDto.setEntInfoList(entList);
        contractCommonInfoResDto.setStatus(kwcContractTrade.getStatus());
        contractCommonInfoResDto.setStatusName(Objects.requireNonNull(ContractStatusEnum.getName(kwcContractTrade.getStatus())).getName());
        List<KwcContractLogisticsUnit> kwcContractLogisticsUnits = kwcContractLogisticsUnitService.queryByContractId(kwcContractTrade.getId());
        if (CollectionUtils.isNotEmpty(kwcContractLogisticsUnits)) {
            for (KwcContractLogisticsUnit kwcContractLogisticsUnit : kwcContractLogisticsUnits) {
                EntInfo entInfo = new EntInfo();
                entInfo.setEntId(kwcContractLogisticsUnit.getEntId());
                entInfo.setEntName(kwcContractLogisticsUnit.getFirmName());
                entList.add(entInfo);
            }
        }
        return contractCommonInfoResDto;
    }
}
