package com.jwipc.finance.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jwipc.api.constant.RestCode;
import com.jwipc.api.dto.ApiResult;
import com.jwipc.constant.FlagConst;
import com.jwipc.exception.DaoException;
import com.jwipc.finance.dto.CompanyAccountApiDTO;
import com.jwipc.finance.entity.CompanyAccountStatement;
import com.jwipc.finance.entity.CompanyAccountStatementDetail;
import com.jwipc.finance.logic.CompanyAccountApiLogic;
import com.jwipc.finance.service.ICompanyAccountStatementDetailService;
import com.jwipc.finance.service.ICompanyAccountStatementService;
import com.jwipc.prop.PriceHandle;
import com.jwipc.supplier.clent.dto.SupplierDTO;
import com.jwipc.supplier.client.SupplierClient;
import com.jwipc.sys.client.TaxClient;
import com.jwipc.sys.client.dto.PurchaseGroupDTO;
import com.jwipc.sys.client.dto.TaxDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author shenyang.ou
 * @date 2025/11/18 17:24
 * @desc
 */
@Service
@RequiredArgsConstructor
public class CompanyAccountApiLogicImpl implements CompanyAccountApiLogic {
    private final TaxClient taxClient;
    private final PriceHandle priceHandle;
    private final SupplierClient supplierClient;
    private final ICompanyAccountStatementService companyAccountStatementService;
    private final ICompanyAccountStatementDetailService companyAccountStatementDetailService;
    @Override
    public ApiResult saveOrUpdate(CompanyAccountApiDTO param) {
        CompanyAccountApiDTO.Head head = param.getHead();

        CompanyAccountStatement companyAccountStatement = new CompanyAccountStatement();
        String DZRQ = head.getDZRQ();
        if (StrUtil.isNotEmpty(DZRQ)) {
            try {
                DZRQ = DZRQ.replaceAll("/", "-");
                Date codeDate = DateUtil.parse(DZRQ, "yyyyMMdd");
                companyAccountStatement.setAccountDate(LocalDateTimeUtil.parse(DateUtil.format(codeDate,"yyyyMMdd"), "yyyyMMdd"));
            } catch (Exception e) {
                return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("请输入正确的对账日期；如：20251111").build();
            }
        }
        String DZQJQ = head.getDZQJQ();
        if (StrUtil.isNotEmpty(DZQJQ)) {
            try {
                DZQJQ = DZQJQ.replaceAll("/", "-");
                Date codeDate = DateUtil.parse(DZQJQ, "yyyyMMdd");
                companyAccountStatement.setInStockStartDate(LocalDateTimeUtil.parse(DateUtil.format(codeDate,"yyyyMMdd"), "yyyyMMdd"));
            } catch (Exception e) {
                return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("请输入正确的对账期间起；如：20251111").build();
            }
        }
        String DZQJZ = head.getDZQJZ();
        if (StrUtil.isNotEmpty(DZQJZ)) {
            try {
                DZQJZ = DZQJZ.replaceAll("/", "-");
                Date codeDate = DateUtil.parse(DZQJZ, "yyyyMMdd");
                companyAccountStatement.setInStockEndDate(LocalDateTimeUtil.parse(DateUtil.format(codeDate,"yyyyMMdd"), "yyyyMMdd"));
            } catch (Exception e) {
                return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("请输入正确的对账期间止；如：20251111").build();
            }
        }

        if (StrUtil.isNotEmpty(head.getSCGSBM())) {
            try {
                SupplierDTO supplierDTO = supplierClient.getSupplierByCode(head.getSCGSBM());
                if (Objects.isNull(supplierDTO)){
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message(StrUtil.format("生产公司编码{}再系统中不存在",head.getSCGSBM())).build();
                }
                if (!"Z001".equals(supplierDTO.getSupplierGroup())){
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message(StrUtil.format("生产公司编码{}不是集团内业务伙伴",head.getSCGSBM())).build();
                }
            } catch (Exception e) {
                return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("请输入正确的对账期间止；如：20251111").build();
            }
        }
        companyAccountStatement.setRemark(head.getBZZ());
        companyAccountStatement.setCurrencyCode(head.getBZ());
        companyAccountStatement.setAccountStatementNo(head.getDZBH());
        String BQJE = head.getBQJE();
        if (StrUtil.isNotEmpty(BQJE)) {
            try {
               new BigDecimal(BQJE);
            } catch (Exception e) {
                return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("请输入正确的本期金额").build();
            }
        }

        //采购组
        final List<TaxDTO> taxDTOS = taxClient.getAll();
        final Map<String, TaxDTO> taxCache = taxDTOS.stream()
                .collect(Collectors.toMap(TaxDTO::getTaxCode, a -> a));
        final Set<String> taxCodes = taxCache.keySet();
        List<CompanyAccountApiDTO.Item> itemList = param.getItems();
        String taxCode = "";
        TaxDTO taxDTO = null;
        Set<String> poTypeSet = new HashSet<>();
        for (CompanyAccountApiDTO.Item item : itemList){
            if (StringUtils.isNotEmpty( item.getSL())&&!taxCodes.contains( item.getSL())){
                return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message(StrUtil.format("明细信息：税率：{}在系统中不存在",item.getSL())).build();
            }
            if (StrUtil.isNotEmpty(item.getDZSL())) {
                try {
                    new BigDecimal(item.getDZSL());
                } catch (Exception e) {
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("明细信息：请输入正确的对账数量").build();
                }
            }
            if (StrUtil.isNotEmpty(item.getKPSL())) {
                try {
                    new BigDecimal(item.getKPSL());
                } catch (Exception e) {
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("明细信息：请输入正确的开票数量").build();
                }
            }
            if (StrUtil.isNotEmpty(item.getHSDJ())) {
                try {
                    new BigDecimal(item.getHSDJ());
                } catch (Exception e) {
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("明细信息：请输入正确的含税单价").build();
                }
            }
            if (StrUtil.isNotEmpty(item.getWSJE())) {
                try {
                    new BigDecimal(item.getWSJE());
                } catch (Exception e) {
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("明细信息：请输入正确的未税金额").build();
                }
            }
            if (StrUtil.isNotEmpty(item.getSE())) {
                try {
                    new BigDecimal(item.getSE());
                } catch (Exception e) {
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("明细信息：请输入正确的税额").build();
                }
            }
            if (StrUtil.isNotEmpty(item.getHSJE())) {
                try {
                    new BigDecimal(item.getHSJE());
                } catch (Exception e) {
                    return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("明细信息：请输入正确的含税金额").build();
                }
            }
            taxCode = item.getSL();
            taxDTO = taxCache.get(taxCode);
            poTypeSet.add(item.getXSDDLX());
        }
        //poTypeSet逗号隔开
        if (CollUtil.isNotEmpty(poTypeSet)){
            companyAccountStatement.setPoType(String.join(",", poTypeSet));
        }
        companyAccountStatement.setTaxCode(taxCode);
        companyAccountStatement.setTaxAmount(new BigDecimal(BQJE));
        //计算未税价格
        assert taxDTO != null;
        companyAccountStatement.setNotTaxAmount(companyAccountStatement.getTaxAmount()
                .divide(taxDTO.getTaxValue().add(BigDecimal.ONE), 6,
                        Objects.equals(priceHandle.getCutType(), FlagConst.N.getCode()) ? RoundingMode.HALF_UP : RoundingMode.DOWN));
        companyAccountStatement.setDifferenceAmount(companyAccountStatement.getTaxAmount().subtract(companyAccountStatement.getNotTaxAmount()));
        companyAccountStatement.setCustomCode(head.getKHBM());
        companyAccountStatement.setCustomName(head.getKHMC());
        companyAccountStatement.setCompanyCode(head.getXSGSBM());
        companyAccountStatement.setCompanyName(head.getXSGSMC());
        companyAccountStatement.setSalesCompanyAddress(head.getXSGSDZ());
        companyAccountStatement.setSalesCompanyContactPhone(head.getXSGSLXDH());
        companyAccountStatement.setSalesCompanySignatorySignature(head.getXSGSDZRQZ());
        companyAccountStatement.setSalesCompanyApprovalDate(head.getXSGSQBRQ());
        companyAccountStatement.setSupplierCode(head.getSCGSBM());
        companyAccountStatement.setSupplierName(head.getSCGSMC());
        companyAccountStatement.setProductionCompanyAddress(head.getSCGSDZ());
        companyAccountStatement.setProductionCompanyContactPhone(head.getSCGSLXDH());
        companyAccountStatement.setProductionCompanySignatorySignature(head.getSCGSDZRQZ());
        companyAccountStatement.setProductionCompanyApprovalDate(head.getSCGSQBRQ());
        //默认
        companyAccountStatement.setOrderType(1);
        companyAccountStatement.setPurchaseGroup("501");
        companyAccountStatement.setPaymentWay("B");
        companyAccountStatement.setPaymentTermCode("Z001");
        companyAccountStatement.setStatus(9);
        companyAccountStatement.setAccountStatementYear(LocalDateTimeUtil.format(companyAccountStatement.getAccountDate(), "yyyy"));
        companyAccountStatement.setAccountStatementMonth(LocalDateTimeUtil.format(companyAccountStatement.getAccountDate(), "MM"));

        CompanyAccountStatement oldCompanyAccountStatement = companyAccountStatementService.getOne(new LambdaQueryWrapper<>(CompanyAccountStatement.class).eq(CompanyAccountStatement::getAccountStatementNo, companyAccountStatement.getAccountStatementNo()).last(" limit 1"));
        if (ObjectUtil.isNotEmpty(oldCompanyAccountStatement)){
            companyAccountStatement.setId(oldCompanyAccountStatement.getId());
            companyAccountStatement.setUpdateTime(LocalDateTime.now());
            companyAccountStatement.setUpdateUserId(1L);
            companyAccountStatement.setDeleteFlag(0);
            companyAccountStatementService.updateById(companyAccountStatement);
            companyAccountStatementDetailService.remove(new LambdaQueryWrapper<>(CompanyAccountStatementDetail.class).eq(CompanyAccountStatementDetail::getAsId, oldCompanyAccountStatement.getId()));
        }else {
            companyAccountStatement.setCreateUserId(1L);
            companyAccountStatement.setCreateTime(LocalDateTime.now());
            companyAccountStatementService.save(companyAccountStatement);
        }

        List<CompanyAccountStatementDetail> detailList = new ArrayList<>();
        for (CompanyAccountApiDTO.Item item : itemList){
            if (StringUtils.isNotEmpty( item.getSL())&&!taxCodes.contains( item.getSL())){
                return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message(StrUtil.format("税率：{}在系统中不存在",item.getSL())).build();
            }
            CompanyAccountStatementDetail detail = new CompanyAccountStatementDetail();
            detail.setItemNo(item.getLBXH());
            detail.setAsId(companyAccountStatement.getId());
            detail.setRowNo(item.getLBXH());
            detail.setAsNo(companyAccountStatement.getAccountStatementNo());
            detail.setCreateUserId(1L);
            detail.setCreateTime(LocalDateTime.now());
            detail.setCustomerPo(item.getKHPO());
            detail.setSalesOrderType(item.getXSDDLX());
            detail.setSalesOrder(item.getXSDD());
            detail.setSalesOrderRowNo(item.getXSDDHH());
            detail.setShipmentDate(item.getCHRQ());
            detail.setDeliveryNote(item.getJHD());
            detail.setDeliveryNoteRowNo(item.getJHDHH());
            detail.setMaterialCode(item.getWLBM());
            detail.setMaterialGroupName(item.getWLZMS());
            detail.setMaterialName(item.getWLMS());
            detail.setCustomerMaterialNumber(item.getKHLH());
            detail.setInvoiceProductName(item.getKPPM());
            detail.setSpecificationModel(item.getGGXH());
            detail.setReconciliationQuantity(StrUtil.isNotEmpty(item.getDZSL())?new BigDecimal(item.getDZSL()) : null);
            detail.setInvoiceQuantity(StrUtil.isNotEmpty(item.getKPSL())?new BigDecimal(item.getKPSL()) : null);
            detail.setUnit(item.getDW());
            detail.setTaxCode(item.getSL());
            detail.setTaxPrice(StrUtil.isNotEmpty(item.getHSDJ())?new BigDecimal(item.getHSDJ()) : null);
            detail.setNotTaxAmount(StrUtil.isNotEmpty(item.getWSJE())?new BigDecimal(item.getWSJE()) : null);
            detail.setDiffTaxAmount(StrUtil.isNotEmpty(item.getSE())?new BigDecimal(item.getSE()) : null);
            detail.setTaxAmount(StrUtil.isNotEmpty(item.getHSJE())?new BigDecimal(item.getHSJE()) : null);
//            //计算未税价格
//            detail.setNotTaxAmount(detail.getTaxAmount()
//                    .divide(taxDTO.getTaxValue().add(BigDecimal.ONE), 6,
//                            Objects.equals(priceHandle.getCutType(), FlagConst.N.getCode()) ? RoundingMode.HALF_UP : RoundingMode.DOWN));
//            detail.setDiffTaxAmount(detail.getTaxAmount().subtract(detail.getNotTaxAmount()));
            detailList.add(detail);
        }
        companyAccountStatementDetailService.saveBatch(detailList);
        return ApiResult.builder().code(RestCode.SAP_SUCCESS.getCode()).message("成功").build();
    }
}
