package com.zt.plat.module.erp.service.erp;

import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.erp.api.ErpExternalApi;
import com.zt.plat.module.erp.api.dto.*;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Validated
public class ErpInvoiceticketServiceImpl implements ErpInvoiceticketService {

    @Resource
    public ErpExternalApi erpExternalApi;

    @Override
    public ErpInvoiceticketSubmitRespDTO sbumitToErp020(ErpInvoiceticketSubmitReqDTO erpInvoiceticketSubmitReqDTO) {
        ErpSubmitReqDTO reqDTO = new ErpSubmitReqDTO();
        reqDTO.setFuncnr("020");
        reqDTO.setBskey(erpInvoiceticketSubmitReqDTO.getId());
        reqDTO.setUsrid(String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        reqDTO.setUsrnm((SecurityFrameworkUtils.getLoginUserNickname()));

        Map<String, Object> req = new HashMap<>();
        req.put("vouchertype", erpInvoiceticketSubmitReqDTO.getVouchertype());
        req.put("voucherno", erpInvoiceticketSubmitReqDTO.getVoucherno());
        req.put("voucheryear", erpInvoiceticketSubmitReqDTO.getVoucheryear());
        reqDTO.setReq(req);
        // 1. 调用ERP接口获取HashMap结果

        Map<String, String> result = erpExternalApi.submitDataToErp(reqDTO);

        // 2. 初始化响应实体
        ErpInvoiceticketSubmitRespDTO respDTO = new ErpInvoiceticketSubmitRespDTO();

        // 3. 基础字段映射（String类型直接赋值，兼容空值）
        respDTO.setPostDate(getStringValue(result, "postDate"));
        respDTO.setSettlementsCode(getStringValue(result, "settlementsCode"));
        respDTO.setState(getStringValue(result, "state"));
        respDTO.setReason(getStringValue(result, "reason"));
        respDTO.setRefDoc(getStringValue(result, "refDoc"));
        respDTO.setRevDoc(getStringValue(result, "revDoc"));
        respDTO.setRevYear(getStringValue(result, "revYear"));
        respDTO.setRevDate(getStringValue(result, "revDate"));

        // 4. 子列表 callBackSettlementDetails 映射
        respDTO.setCallBackSettlementDetails(convertSettlementDetails(result));

        return respDTO;
    }


    /**
     * 转换采购发票过账差异明细列表
     * 假设HashMap中子列表字段格式为：callBackSettlementDetails[0].factoryCode、callBackSettlementDetails[0].materialCode...
     */
    private List<ErpInvoiceticketSubmitRespDTO.CallBackSettlementDetail> convertSettlementDetails(Map<String, String> result) {
        List<ErpInvoiceticketSubmitRespDTO.CallBackSettlementDetail> detailList = new ArrayList<>();
        if (result == null) {
            return detailList;
        }

        // 按索引遍历子列表数据，直到无对应字段为止
        int index = 0;
        while (true) {
            // 拼接子字段的key（根据实际返回的key格式调整，此处为标准嵌套格式）
            String factoryCodeKey = String.format("callBackSettlementDetails[%d].factoryCode", index);
            String materialCodeKey = String.format("callBackSettlementDetails[%d].materialCode", index);
            String matDocKey = String.format("callBackSettlementDetails[%d].matDoc", index);
            String materialDescKey = String.format("callBackSettlementDetails[%d].materialDesc", index);
            String differenceAmountKey = String.format("callBackSettlementDetails[%d].differenceAmount", index);

            // 若核心字段（如factoryCode）为空，说明无更多子项，退出循环
            if (StringUtils.isBlank(getStringValue(result, factoryCodeKey))) {
                break;
            }

            // 构建子明细实体
            ErpInvoiceticketSubmitRespDTO.CallBackSettlementDetail detail = new ErpInvoiceticketSubmitRespDTO.CallBackSettlementDetail();
            detail.setFactoryCode(getStringValue(result, factoryCodeKey));
            detail.setMaterialCode(getStringValue(result, materialCodeKey));
            detail.setMatDoc(getStringValue(result, matDocKey));
            detail.setMaterialDesc(getStringValue(result, materialDescKey));
            // 金额字段转换（兼容空值和非数字场景）
            detail.setDifferenceAmount(getBigDecimalValue(result, differenceAmountKey));

            detailList.add(detail);
            index++;
        }

        // 无数据时返回null，避免前端接收空列表
        return detailList.isEmpty() ? null : detailList;
    }

    /**
     * 安全获取String值，避免null指针
     */
    private String getStringValue(Map<String, String> map, String key) {
        return map.getOrDefault(key, StringUtils.EMPTY);
    }

    /**
     * 安全转换BigDecimal，处理空值和格式错误
     */
    private BigDecimal getBigDecimalValue(Map<String, String> map, String key) {
        String value = map.get(key);
        if (StringUtils.isBlank(value)) {
            return null;
        }
        try {
            return new BigDecimal(value);
        } catch (NumberFormatException e) {
            // 若金额格式错误，可根据业务选择返回null或抛出异常
            return null;
        }
    }

    @Override
    public Map<String, String> sbumitToErp098(Map<String, Object> param) {
        ErpSubmitReqDTO reqDTO = new ErpSubmitReqDTO();
        reqDTO.setFuncnr("098");
        reqDTO.setBskey(param.get("id").toString());
        reqDTO.setUsrid(String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        reqDTO.setUsrnm((SecurityFrameworkUtils.getLoginUserNickname()));
        param.remove("id");
        reqDTO.setReq(param);
        return erpExternalApi.submitDataToErp(reqDTO);
    }

    @Override
    public Map<String, String> sbumitToErp096(ErpElectronicInvoiceSubmitReqDTO erpElectronicInvoiceSubmitReqDTO) {
        ErpSubmitReqDTO reqDTO = new ErpSubmitReqDTO();
        reqDTO.setFuncnr("096");
        reqDTO.setBskey(erpElectronicInvoiceSubmitReqDTO.getId());
        reqDTO.setUsrid(String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        reqDTO.setUsrnm((SecurityFrameworkUtils.getLoginUserNickname()));
        Map<String, Object> req = new HashMap<>();
        req.put("bill_date", erpElectronicInvoiceSubmitReqDTO.getBill_date());
        req.put("provi_estimate", erpElectronicInvoiceSubmitReqDTO.getProvi_estimate());
        req.put("bline_date", erpElectronicInvoiceSubmitReqDTO.getBline_date());
        req.put("bill_text", erpElectronicInvoiceSubmitReqDTO.getBill_text());
        req.put("no_invoicing", erpElectronicInvoiceSubmitReqDTO.getNo_invoicing());
        req.put("invoice_type", erpElectronicInvoiceSubmitReqDTO.getInvoice_type());
        req.put("invoice_note", erpElectronicInvoiceSubmitReqDTO.getInvoice_note());
        req.put("reversal_reason", erpElectronicInvoiceSubmitReqDTO.getReversal_reason());
        req.put("item", erpElectronicInvoiceSubmitReqDTO.getItem());
        req.put("cond", erpElectronicInvoiceSubmitReqDTO.getCond());
        req.put("filedata", erpElectronicInvoiceSubmitReqDTO.getBline_date());
        reqDTO.setReq(req);
        return erpExternalApi.submitDataToErp(reqDTO);
    }

    @Override
    public Map<String, String> sbumitToErp097(ErpElectronicInvoiceReversalReqDTO reqDTO) {
        ErpSubmitReqDTO submitReqDTO = new ErpSubmitReqDTO();
        submitReqDTO.setFuncnr("097");
        submitReqDTO.setBskey(reqDTO.getId());
        submitReqDTO.setUsrid(String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        submitReqDTO.setUsrnm((SecurityFrameworkUtils.getLoginUserNickname()));
        Map<String, Object> req = new HashMap<>();
        req.put("billdoc", reqDTO.getBilldoc());
        req.put("postingdate", reqDTO.getPostingdate());
        req.put("reason", reqDTO.getReason());
        req.put("no_invoicing", reqDTO.getNo_invoicing());
        req.put("filedata", reqDTO.getFiledata());
        submitReqDTO.setReq( req);
        return erpExternalApi.submitDataToErp(submitReqDTO);
    }


}
