package com.trade.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.trade.service.credit.domain.BizCreditApply;
import com.trade.service.credit.domain.vo.BizCreditApplyVO;
import com.trade.service.enterprise.customer.domain.Enterprise;
import com.trade.service.enterprise.customer.domain.EnterpriseChangeRecord;
import com.trade.service.enterprise.customer.domain.EnterpriseRelatedPerson;
import com.trade.service.enterprise.customer.dto.EnterpriseDto;
import com.trade.service.enterprise.customer.dto.EnterpriseRelatedPersonDto;
import com.trade.service.thirdparty.xiaotu.dto.CustomsDeclarationResponse;
import com.trade.service.thirdparty.xiaotu.dto.filingdoc.FilingDocWriteItemDetailGoods;
import com.trade.service.trade.purchasecontract.dto.PurchaseCommodityDto;
import com.trade.service.trade.purchaseorder.domain.PurchaseOrderCommodity;
import com.trade.service.trade.purchaseorder.dto.PurchaseOrderCommodityTL;
import com.trade.service.trade.salescontract.domain.ContractTerms;
import com.trade.service.trade.salescontract.dto.ContractCommodityDto;
import com.trade.service.trade.salesorder.domain.CustomsDeclarationGoods;
import com.trade.service.trade.salesorder.domain.SalesOrder;
import com.trade.service.trade.salesorder.domain.SalesOrderGoods;
import com.trade.service.trade.salesorder.domain.SalesOrderLogistics;
import com.trade.service.trade.salesorder.dto.GoodsInfo4TL;
import com.trade.service.trade.salesorder.dto.SalesOrderDeliverDTO;
import com.trade.service.trade.salesorder.vo.SalesOrderGoodsVO;
import com.trade.service.trade.salesorder.vo.SalesOrderPayInfoVO;
import com.trade.service.trade.salesorder.vo.SalesOrderVO;
import com.trade.service.tradingplatform.domain.TradingPlatformQualification;
import com.trade.service.tradingplatform.dto.TradingPlatformQualificationDto;
import org.mapstruct.*;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Mapper
public interface TransStruct {

    BizCreditApply vO2BizCreditApply(BizCreditApplyVO bizCreditApplyVO);

    @IterableMapping(qualifiedByName = "transSalesOrder2GoodsInfo4TL")
    List<GoodsInfo4TL> transOrder2GoodsInfo4TLList(List<SalesOrderGoods> salesOrderGoodsList);

    SalesOrderLogistics transOrderDeliver2OrderLogistics(SalesOrderDeliverDTO orderDeliverDTO);

    @Mappings({
            @Mapping(source = "price", target = "unitPrice"),
            @Mapping(source = "packingSpecifications", target = "packages"),
            @Mapping(source = "declarationName", target = "goodsName"), @Mapping(source = "priceTotal", target = "amount")
    })
    @Named("transSalesOrder2GoodsInfo4TL")
    GoodsInfo4TL transSalesOrder2GoodsInfo4TL(SalesOrderGoods salesOrderGoods);

    SalesOrderVO transSalesOrder2SalesOrderVO(SalesOrder salesOrder);

    SalesOrderPayInfoVO transContractTerms2SalesOrderPayInfoVO(ContractTerms contractTerms);

    Enterprise transDto2Enterprise(EnterpriseDto enterpriseDto);

    EnterpriseDto transEnterprise2Dto(Enterprise enterpriseD);

    EnterpriseRelatedPerson transEnterpriseRelatedPerson2Dto(EnterpriseRelatedPersonDto personDto);

    EnterpriseRelatedPersonDto transDto2EnterpriseRelatedPerson(EnterpriseRelatedPerson person);

    @Mapping(source = "changeRecordId", target = "id")
    EnterpriseChangeRecord transEnterpriseDto2EnterpriseChangeRecord(EnterpriseDto enterpriseDto);

    EnterpriseDto transEnterpriseChangeRecord2EnterpriseDto(EnterpriseChangeRecord changeRecord);

    @Mappings({
            @Mapping(target = "id", ignore = true), @Mapping(target = "createBy", ignore = true),
            @Mapping(target = "gmtCreate", ignore = true), @Mapping(target = "updateBy", ignore = true),
            @Mapping(target = "gmtModified", ignore = true)
    })
    TradingPlatformQualification transDto2TradingPlatformQualification(TradingPlatformQualificationDto notifyDto);

    TradingPlatformQualificationDto transTradingPlatformQualification2Dto(
            TradingPlatformQualification notify);

    @Mapping(source = "ckhth", target = "saleOrderNo")
    CustomsDeclarationGoods transXTResponseToCustomsDeclarationGoods(CustomsDeclarationResponse customsDeclarationResponse);

    @IterableMapping(qualifiedByName = "transOrderGoods4FilingDoc")
    List<FilingDocWriteItemDetailGoods> transSalesOrderGoodsList4FilingDoc(List<SalesOrderGoodsVO> salesOrderGoodsList);

    @Mappings({
            @Mapping(source = "name", target = "spmc"), @Mapping(source = "count", target = "sl")
    })
    @Named("transOrderGoods4FilingDoc")
    FilingDocWriteItemDetailGoods transSalesOrderGoods4FilingDoc(SalesOrderGoodsVO salesOrderGoods);

    @IterableMapping(qualifiedByName = "transPurchaseCommodity4FilingDoc")
    List<FilingDocWriteItemDetailGoods> transPurchaseOrderDetailList4FilingDoc(
            List<PurchaseCommodityDto> commodityList);

    @Mappings({
            @Mapping(source = "name", target = "spmc"), @Mapping(source = "number", target = "sl")
    })
    @Named("transPurchaseCommodity4FilingDoc")
    FilingDocWriteItemDetailGoods transPurchaseCommodity4FilingDoc(PurchaseCommodityDto purchaseCommodityDto);

    class MapStruct {

        public static List<String> strToList(String str) {
            if (StrUtil.isNotEmpty(str)) {
                return Arrays.asList(str.split(","));
            }
            return null;
        }

        public static String listToStr(List<String> list) {
            if (CollUtil.isNotEmpty(list)) {
                return list.stream().map(String::valueOf).collect(Collectors.joining(","));
            }
            return null;
        }

        public static String concatenate(String hsCode, String name) {
            return hsCode + "+" + name;
        }

        public static String getTaxAmount(BigDecimal amount, BigDecimal taxRefundRate) {
            return amount.multiply(taxRefundRate).toPlainString();
        }
    }

    @IterableMapping(qualifiedByName = "transPurchaseOrderCommodityForTLList")
    List<PurchaseOrderCommodityTL> transPurchaseOrderCommodityForTLList(List<PurchaseOrderCommodity> commodities);

    @Mappings({
            @Mapping(target = "hsCodeAndName", expression = "java(MapStruct.concatenate(commodity.getHsCode(), commodity.getName()))"),
            @Mapping(source = "number", target = "count"), @Mapping(source = "priceUnit", target = "price"),
            @Mapping(source = "taxRefundRate", target = "addedTaxRate"),
            @Mapping(target = "taxAmount", expression = "java(MapStruct.getTaxAmount(commodity.getAmount(), commodity.getTaxRefundRate()))"),
    })
    @Named("transPurchaseOrderCommodityForTLList")
    PurchaseOrderCommodityTL transPurchaseOrderCommodityForTL(PurchaseOrderCommodity commodity);

    @Mappings({
            @Mapping(source = "declarationName", target = "goodsName"),
            @Mapping(source = "packSpec", target = "packages"),
            @Mapping(source = "measurementUnit", target = "unit"),
            @Mapping(source = "number", target = "count"),
            @Mapping(source = "priceUnit", target = "price"),
            @Mapping(source = "addedTaxRate", target = "taxRate"),
            @Mapping(source = "totalAmount", target = "amount"),
    })
    @Named("transPurchaseCommodity2ContractCommodity")
    ContractCommodityDto transPurchaseCommodity2ContractCommodity(PurchaseCommodityDto purchaseCommodityDto);

    @IterableMapping(qualifiedByName = "transPurchaseCommodity2ContractCommodity")
    List<ContractCommodityDto> transPurchaseCommodityList2ContractCommodityList(List<PurchaseCommodityDto> purchaseCommodityDtoList);

}
