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.domain.Enterprise;
import com.trade.service.enterprise.domain.EnterpriseChangeRecord;
import com.trade.service.enterprise.domain.EnterpriseRelatedPerson;
import com.trade.service.enterprise.dto.EnterpriseDto;
import com.trade.service.enterprise.dto.EnterpriseRelatedPersonDto;
import com.trade.service.order.domain.PurchaseOrderCommodity;
import com.trade.service.order.dto.PurchaseOrderCommodityTL;
import com.trade.service.sales.domain.ContractTerms;
import com.trade.service.salesorder.domain.SalesOrder;
import com.trade.service.salesorder.domain.SalesOrderGoods;
import com.trade.service.salesorder.domain.SalesOrderLogistics;
import com.trade.service.salesorder.dto.GoodsInfo4TL;
import com.trade.service.salesorder.dto.SalesOrderDeliverDTO;
import com.trade.service.salesorder.vo.SalesOrderPayInfoVO;
import com.trade.service.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 = "name", target = "goodsName"), @Mapping(source = "priceTotal", target = "amount")
    })
    @Named("transSalesOrder2GoodsInfo4TL")
    GoodsInfo4TL transSalesOrder2GoodsInfo4TL(SalesOrderGoods salesOrderGoods);

    SalesOrderVO transSalesOrder2SalesOrderVO(SalesOrder salesOrder);

    SalesOrderPayInfoVO transContractTerms2SalesOrderPayInfoVO(ContractTerms contractTerms);

    @Mapping(source = "authorizationFile.id", target = "authorizationFile")
    Enterprise transDto2Enterprise(EnterpriseDto enterpriseDto);

    @Mapping(source = "authorizationFile", target = "authorizationFile.id")
    EnterpriseDto transEnterprise2Dto(Enterprise enterpriseD);

    EnterpriseRelatedPerson transEnterpriseRelatedPerson2Dto(EnterpriseRelatedPersonDto personDto);

    EnterpriseRelatedPersonDto transDto2EnterpriseRelatedPerson(EnterpriseRelatedPerson person);

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

    @Mapping(source = "authorizationFile", target = "authorizationFile.id")
    EnterpriseDto transEnterpriseChangeRecord2EnterpriseDto(EnterpriseChangeRecord changeRecord);

    @Mappings({
            @Mapping(source = "commoditySpecialQualification.id", target = "commoditySpecialQualification"),
            @Mapping(target = "hisExportCommodityClass", expression = "java(MapStruct.listToStr(notifyDto.getHisExportCommodityClass()))"),
            @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);

    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);
}
