package com.sckw.payment.service.operate;

import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.page.PageRes;
import com.sckw.core.model.vo.TableTop;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringTimeUtil;
import com.sckw.order.api.dubbo.TradeOrderInfoService;
import com.sckw.order.api.model.*;
import com.sckw.payment.dao.KwpLedgerTradeMapper;
import com.sckw.payment.model.KwpLedgerTrade;
import com.sckw.payment.model.KwpLedgerTradeOrder;
import com.sckw.payment.model.constant.LedgerEnum;
import com.sckw.payment.model.constant.TradeUnitType;
import com.sckw.payment.model.dto.ILedger;
import com.sckw.payment.model.dto.OrderDto;
import com.sckw.payment.model.vo.LedgerSell;
import com.sckw.payment.model.vo.req.LedgerListReq;
import com.sckw.payment.model.vo.req.TradeReq;
import com.sckw.payment.model.vo.res.LedgerTradeDetailVo;
import com.sckw.payment.service.AbsLedger;
import com.sckw.payment.service.KwpLedgerTradeOrderService;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

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

/**
 * @author xucaiqin
 * @date 2023-07-10 16:38:36
 */

@Service
@Slf4j
@RequiredArgsConstructor
public class LedgerTradeService extends AbsLedger {
    private final KwpLedgerTradeMapper tradeMapper;
    private final KwpLedgerTradeOrderService tradeOrderService;

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

    /**
     * 转换字典数据
     *
     * @param list
     */
    private void changeDict(List<? extends ILedger> list) {
        List<SysDictResDto> taxRateDict = remoteSystemService.queryDictByType(DictTypeEnum.TAX_RATE.getType());
        Map<String, String> taxRateMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> tradingMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);

        if (!CollectionUtils.isEmpty(taxRateDict)) {
            taxRateMap = taxRateDict.stream().collect(Collectors.toMap(SysDictResDto::getValue, SysDictResDto::getLabel, (a, b) -> a));
        }
        List<SysDictResDto> tradingDict = remoteSystemService.queryDictByType(DictTypeEnum.TRADE_TYPE.getType());
        if (!CollectionUtils.isEmpty(tradingDict)) {
            tradingMap = tradingDict.stream().collect(Collectors.toMap(SysDictResDto::getValue, SysDictResDto::getLabel, (a, b) -> a));
        }
        for (ILedger tradeDto : list) {
            String trading = tradeDto.getTrading();
            tradeDto.setTradingLabel(tradingMap.get(trading));
            Integer taxRate = tradeDto.getTaxRate();
            tradeDto.setTaxRateLabel(taxRateMap.get(String.valueOf(taxRate)));

            tradeDto.setStatusLabel(LedgerEnum.getDesc(tradeDto.getStatus()));
            UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(tradeDto.getCreateBy());
            if (Objects.nonNull(userCacheResDto)) {
                tradeDto.setCreateByName(userCacheResDto.getName());
            }
        }
    }

    /**
     * 填充时间等参数
     *
     * @param tradeReq 请求参数
     */
    private void fillPara(TradeReq tradeReq) {
        if (StringUtils.isNotBlank(tradeReq.getStartCreateTime())) {
            tradeReq.setStartCreateTime(StringTimeUtil.fillStart(tradeReq.getStartCreateTime()));
        }
        if (StringUtils.isNotBlank(tradeReq.getEndCreateTime())) {
            tradeReq.setEndCreateTime(StringTimeUtil.fillEnd(tradeReq.getEndCreateTime()));
        }
    }

    /**
     * 销售方
     *
     * @param tradeReq
     * @return
     */
    public PageRes<LedgerSell> list(TradeReq tradeReq) {
        fillPara(tradeReq);
        if (tradeReq.getPage() != 0 && tradeReq.getPageSize() != 0) {
            PageHelper.startPage(tradeReq.getPage(), tradeReq.getPageSize());
        }
        tradeReq.setUnitType(TradeUnitType.PURCHASE);
        tradeReq.setUnitTypeTwo(TradeUnitType.SELL);
        List<LedgerSell> ledgerTradeDto = tradeMapper.list(tradeReq);
        //字典转换
        if (!CollectionUtils.isEmpty(ledgerTradeDto)) {
            changeDict(ledgerTradeDto);
            return new PageRes<>(ledgerTradeDto);
        }
        return new PageRes<>();
    }

    /**
     * 按分类统计对账单表头数量
     *
     * @param tradeReq 查询参数
     * @return
     */
    public List<TableTop> orderCount(TradeReq tradeReq) {
        Map<String, Long> map = tradeMapper.countOrder2(tradeReq);
        TableTop ledgerCountVo;
        List<TableTop> res = new ArrayList<>();
        for (LedgerEnum value : LedgerEnum.values()) {
            ledgerCountVo = new TableTop();
            ledgerCountVo.setTotal(Math.toIntExact(map.get(value.getLabel())));
            ledgerCountVo.setName(value.getDesc());
            ledgerCountVo.setValue(value.getStatus());
            res.add(ledgerCountVo);
        }
        return res;
    }

    private OrderDto changeOrder(OrderDetailRes orderDetailRes) {
        OrderDto orderDto = new OrderDto();
        BeanUtils.copyProperties(orderDetailRes, orderDto);
        List<UnitInfoDetailRes> unitInfo = orderDetailRes.getUnitInfo();
        if (!CollectionUtils.isEmpty(unitInfo)) {
            for (UnitInfoDetailRes unitInfoDetailRes : unitInfo) {
                //2-销售
                if (StringUtils.equals(unitInfoDetailRes.getUnitType(), "2")) {
                    orderDto.setSupplyEntId(unitInfoDetailRes.getEntId());
                    orderDto.setSupplyFirmName(unitInfoDetailRes.getFirmName());
                }
                //1-采购
                if (StringUtils.equals(unitInfoDetailRes.getUnitType(), "1")) {
                    orderDto.setProcureEntId(unitInfoDetailRes.getEntId());
                    //采购企业名称
                    orderDto.setProcureFirmName(unitInfoDetailRes.getFirmName());
                }
            }
        }
        ContractInfo contractInfo = orderDetailRes.getContractInfo();
        if (Objects.nonNull(contractInfo)) {
            orderDto.setContractId(contractInfo.getContractId());
            orderDto.setContractNo(contractInfo.getContractNo());
            orderDto.setContractName(contractInfo.getContractName());
            orderDto.setContractSigningWay(contractInfo.getContractSigningWay());
        }
        GoodsInfoDetailRes goodsInfo = orderDetailRes.getGoodsInfo();
        if (Objects.nonNull(goodsInfo)) {
            orderDto.setGoodsId(goodsInfo.getGoodsId());
            orderDto.setGoodsSpec(goodsInfo.getSpec());
            orderDto.setGoodsName(goodsInfo.getName());
            orderDto.setGoodsType(goodsInfo.getGoodsType());
            orderDto.setGoodsTypeLabel(goodsInfo.getGoodsTypeLabel());
            orderDto.setUnit(goodsInfo.getUnit());
            orderDto.setUnitLabel(goodsInfo.getUnitLabel());
            orderDto.setUnitPrice(goodsInfo.getUnitPrice());
            orderDto.setGoodsAmount(goodsInfo.getGoodsAmount());
            orderDto.setTaxRate(goodsInfo.getTaxRate());
            orderDto.setTaxRateLabel(goodsInfo.getTaxRateLabel());
        }
        List<AddressInfoDetail> addressInfo = orderDetailRes.getAddressInfo();
        if (!CollectionUtils.isEmpty(addressInfo)) {
            for (AddressInfoDetail addressInfoDetail : addressInfo) {
                if (StringUtils.equals(addressInfoDetail.getAddressType(), "1")) {
                    orderDto.setLoadName(addressInfoDetail.getName());
                    orderDto.setLoadDetailAddressInfo(addressInfoDetail.getDetailAddress());
                }
                if (StringUtils.equals(addressInfoDetail.getAddressType(), "2")) {
                    orderDto.setUnloadName(addressInfoDetail.getName());
                    orderDto.setUnloadDetailAddressInfo(addressInfoDetail.getDetailAddress());
                }
            }
        }
        orderDto.setTOrderId(orderDetailRes.getId());
        return orderDto;
    }

    private LedgerTradeDetailVo getDetail(KwpLedgerTrade ledgerTradeDto) {
        List<KwpLedgerTradeOrder> kwpLedgerTradeOrders = tradeOrderService.queryList(ledgerTradeDto.getId());
        LedgerTradeDetailVo ledgerTradeDetailVo = new LedgerTradeDetailVo();
        ledgerTradeDetailVo.setId(ledgerTradeDto.getId());
        ledgerTradeDetailVo.setTLedgerNo(ledgerTradeDto.getTLedgerNo());
        ledgerTradeDetailVo.setName(ledgerTradeDto.getName());
        SysDictResDto trading = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.TRADE_TYPE.getType(), ledgerTradeDto.getTrading());
        ledgerTradeDetailVo.setTrading(ledgerTradeDto.getTrading());
        ledgerTradeDetailVo.setTradingLabel(Objects.nonNull(trading) ? trading.getLabel() : "");
        SysDictResDto taxRate = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.TAX_RATE.getType(), String.valueOf(ledgerTradeDto.getTaxRate()));
        ledgerTradeDetailVo.setTaxRate(ledgerTradeDto.getTaxRate());
        ledgerTradeDetailVo.setTaxRateLabel(Objects.nonNull(taxRate) ? taxRate.getLabel() : "");
        ledgerTradeDetailVo.setTotalPrice(ledgerTradeDto.getTotalPrice());
        ledgerTradeDetailVo.setSettlePrice(ledgerTradeDto.getSettlePrice());
        ledgerTradeDetailVo.setActualPrice(ledgerTradeDto.getActualPrice());
        ledgerTradeDetailVo.setStartTime(ledgerTradeDto.getStartTime());
        ledgerTradeDetailVo.setEndTime(ledgerTradeDto.getEndTime());
        ledgerTradeDetailVo.setRemark(ledgerTradeDto.getRemark());
        List<Long> collect = kwpLedgerTradeOrders.stream().map(KwpLedgerTradeOrder::getTOrderId).toList();
        List<OrderDto> detailRes = new ArrayList<>();
        OrderDetailRes orderDetailById;
        //查询贸易订单详情
        for (Long aLong : collect) {
            try {
                orderDetailById = tradeOrderInfoService.getOrderDetailById(aLong);
            } catch (Exception e) {
                log.error("不存在该订单！tradeOrderInfoService.getOrderDetailById({})", aLong, e);
                continue;
            }
            detailRes.add(changeOrder(orderDetailById));
        }
        ledgerTradeDetailVo.setOrderList(detailRes);
        return ledgerTradeDetailVo;
    }

    /**
     * 查询对账单详情
     *
     * @param id 对账单id
     * @return 对账单详情
     */
    public LedgerTradeDetailVo queryDetail(Long id) {
        KwpLedgerTrade ledgerTrade = tradeMapper.selectById(id);
        orderCheck(ledgerTrade);
        return getDetail(ledgerTrade);
    }

    public PageRes<OrderDto> orderList(LedgerListReq ledgerListReq) {
        PageHelper.startPage(ledgerListReq.getPage(), ledgerListReq.getPageSize());
        List<KwpLedgerTradeOrder> kwpLedgerLogisticsOrders = tradeOrderService.queryList(ledgerListReq.getIdLong());
        if (CollectionUtils.isEmpty(kwpLedgerLogisticsOrders)) {
            return new PageRes<>();
        }
        PageInfo<KwpLedgerTradeOrder> pageInfo = new PageInfo<>(kwpLedgerLogisticsOrders);
        List<OrderDto> detailRes = new ArrayList<>();
        for (KwpLedgerTradeOrder kwpLedgerLogisticsOrder : kwpLedgerLogisticsOrders) {
            OrderDetailRes orderDetailById = tradeOrderInfoService.getOrderDetailById(kwpLedgerLogisticsOrder.getTOrderId());
            log.info("销售订单：{}", JSONObject.toJSONString(orderDetailById));
            detailRes.add(changeOrder(orderDetailById));
        }
        return PageRes.build(pageInfo, detailRes);
    }

    /**
     * 运营端通过ids查询需要导出的数据
     *
     * @param idList
     * @return
     */
    public List<LedgerSell> queryIds(List<Long> idList) {
        List<LedgerSell> ledgerSells = tradeMapper.selectIds(idList);
        changeDict(ledgerSells);
        return ledgerSells;
    }
}
