package nccloud.web.gl.accountrep.action;

import nc.bs.logging.Logger;
import nc.vo.pub.BusinessException;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import nccloud.framework.web.container.SessionContext;
import nccloud.framework.web.json.JsonFactory;
import nccloud.pubitf.gl.account.IAccountReportWebService;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class AccountBalanceTotalQueryAction implements ICommonAction {
    public AccountBalanceTotalQueryAction() {
    }
    public Object doAction(IRequest request) {
        String json = request.read();
        Logger.info("busiParam:" + json);
        Map<String, Object> paraMap = (Map) JsonFactory.create().fromJson(json, Map.class);
        this.setAppcode(paraMap);

        try {
            return this.doQuery(getParaMap(paraMap));
        } catch (BusinessException e) {
            ExceptionUtils.wrapException(e);
            return null;
        }
    }
    public Object doQuery(Map<String, Object> paraMap) throws BusinessException {

        // 科目余额表数据
        Map<String, Object> result = ((IAccountReportWebService) ServiceLocator.find(IAccountReportWebService.class)).queryAccBalance((Map<String, Object>) paraMap.get("second"));
        // 科目辅助余额表数据
        Map<String, Object> result1 = ((IAccountReportWebService) ServiceLocator.find(IAccountReportWebService.class)).querySubjAssBalanceBooks((Map<String, Object>) paraMap.get("first"));
        List<Map<String, Object>> data = (List<Map<String, Object>>) result.get("data");
        List<Map<String, Object>> data1 = (List<Map<String, Object>>) result1.get("data");

        // 过滤掉 data1 中 assname 为空的数据
        data1 = data1.stream()
                .filter(item -> item.get("assname") != null && !item.get("assname").toString().trim().isEmpty())
                .collect(Collectors.toList());

        // 创建一个映射，根据 acccode 快速查找 data 中的元素
        Map<String, Map<String, Object>> dataMap = data.stream()
                .collect(Collectors.toMap(item -> (String) item.get("acccode"), item -> item));
        for (Map<String, Object> item : data) {
            String endorint = (String) item.get("endorint");
            BigDecimal endlocamount = parseEndlocamount((String) item.get("endlocamount")) ;
            if ("贷".equals(endorint)) {
                item.put("endlocamount", endlocamount.negate());
            }
        }
        // 构造新的 Map，存储每个父级科目的期末余额之和
        Map<String, BigDecimal> sumMap = new HashMap<>();

        // 构造新的列表
        List<Map<String, Object>> mergedList = new ArrayList<>();
        DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");
        List<BigDecimal> bigDecimals = new ArrayList<>();
        for (Map<String, Object> item : data1) {
            Map<String, Object> linkMap = (Map<String, Object>) item.get("link");
            String acccode = (String) linkMap.get("acccode");

            String accname = (String) item.get("accname");
            String parentAcccode = acccode;
            Map<String, Object> parentItem = dataMap.get(parentAcccode);

            if (parentItem != null) {
                String endlocamountStr = (String) item.get("endlocamount");
                String endorint = (String) item.get("endorint");
                BigDecimal endlocamount = parseEndlocamount(endlocamountStr);
               // 构造新的 Map
                Map<String, Object> newItem = new HashMap<>();
                newItem.put("endlocamount", decimalFormat.format(endlocamount));

                // 根据 endorint 调整 endlocamount 的符号
                if ("贷".equals(endorint)) {
                    endlocamount = endlocamount.negate();
                }
                bigDecimals.add(endlocamount);
                // 更新 sumMap
                sumMap.put(parentAcccode, sumMap.getOrDefault(parentAcccode, BigDecimal.ZERO).add(endlocamount));

                newItem.put("pacccode", parentAcccode);
                newItem.put("pendorint", parentItem.get("endorint"));
                newItem.put("paccname", parentItem.get("accname"));
                newItem.put("pendlocamount", parentItem.get("endlocamount"));
                newItem.put("acccode", acccode);
                newItem.put("accname", accname); // 假设 data1 中没有 accname，使用父级的 accname
                newItem.put("assname", item.get("assname"));
                newItem.put("endorint", item.get("endorint"));
//                newItem.put("endlocamount", decimalFormat.format(endlocamount));
                mergedList.add(newItem);
            }
        }
        BigDecimal sum=BigDecimal.valueOf(0);
        for (BigDecimal bigDecimal : bigDecimals){
            sum=sum.add(bigDecimal);
        }
        List<Map<String, Object>> toBeRemoved = new ArrayList<>();
// 计算每个父级科目的 endlocamount 和所有关联 data1 中 endlocamount 的差值
        for (Map<String, Object> item : mergedList) {
            String parentAcccode = (String) item.get("pacccode");
            BigDecimal endlocamount =BigDecimal.ZERO;
            if( item.get("pendlocamount") instanceof String){
                String endlocamountStr = (String) item.get("pendlocamount");
                 endlocamount = parseEndlocamount(endlocamountStr);
            }else if( item.get("pendlocamount") instanceof BigDecimal){
                endlocamount = (BigDecimal) item.get("pendlocamount");
            }

//            BigDecimal endlocamount = (BigDecimal) item.get("pendlocamount");
            BigDecimal sumEndlocamount = sumMap.get(parentAcccode);
            BigDecimal difference = sumEndlocamount.subtract(endlocamount);
            if (difference.compareTo(BigDecimal.ZERO) == 0) {
                toBeRemoved.add(item);
            } else {
                if(endlocamount.compareTo(BigDecimal.ZERO) < 0){
                    item.put("pendlocamount",decimalFormat.format(endlocamount.negate()) );
                }else{
                    item.put("pendlocamount",decimalFormat.format(endlocamount) );
                }
                item.put("difference", decimalFormat.format(difference));
            }
        }
        mergedList.removeAll(toBeRemoved);
//        for (int i = 1; i < mergedList.size(); i++) {
//            mergedList.get(i).put("pacccode", "");
//            mergedList.get(i).put("paccname", "");
//            mergedList.get(i).put("pendlocamount", "");
//            mergedList.get(i).put("difference", "");
//        }
        //{"busiParamJson":"{\"pk_accountingbook\":[\"1001A110000000001PFH\"],\"pk_unit\":[],\"multbusi\":false,\"usesubjversion\":\"N\",\"versiondate\":\"2025-01-02\",\"startlvl\":\"1\",\"endlvl\":\"1\",\"isleave\":true,\"isoutacc\":\"N\",\"startyear\":\"2024\",\"endyear\":\"2024\",\"startperiod\":\"12\",\"endperiod\":\"12\",\"startdate\":\"2024-12-01\",\"endtdate\":\"2024-12-31\",\"includeuntally\":\"N\",\"includeerror\":\"N\",\"includeplcf\":\"Y\",\"includerc\":\"N\",\"pk_currtype\":\"本币\",\"returncurr\":\"1\",\"mutibook\":\"N\",\"showzerooccur\":\"N\",\"showzerobalanceoccur\":\"Y\",\"sumbysubjtype\":\"N\",\"showupsubj\":\"N\",\"currplusacc\":\"Y\",\"balanceori\":\"-1\",\"twowaybalance\":\"N\",\"istree\":\"Y\",\"qryObjs\":[],\"pk_accasoa\":[\"1001A1100000000017SV\"]}","sysParamJson":{"busiaction":"科目辅助余额表-查询","appcode":"20028003","tabid":"","ts":1735815136860,"from":"","pagecs":1735804016325}}

        // 输出合并后的列表
        for (Map<String, Object> item : mergedList) {
            System.out.println(item);
        }
        return mergedList;
    }

    // 解析 endlocamount 字符串为 double 类型
    private static BigDecimal parseEndlocamount(String endlocamountStr) {
        if (endlocamountStr == null || endlocamountStr.isEmpty()) {
            return BigDecimal.ZERO;
        }
        // 去除逗号
        endlocamountStr = endlocamountStr.replace(",", "");
        try {
            return BigDecimal.valueOf(Double.parseDouble(endlocamountStr));
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }
    private Map<String,Object> getParaMap(Map<String, Object> params) {
        // 获取传入的参数
        List<String> pkAccountingBook = (List<String>) params.get("pk_accountingbook");
//1001A1100000000017TP
        List<String> pkAccasoa = (List<String>) params.get("pk_accasoa");
//        pkAccasoa.add("1001A1100000000017TP");
        String startYear = (String) params.get("startyear");
        String endYear = (String) params.get("endyear");
        String startPeriod = (String) params.get("startperiod");
        String endPeriod = (String) params.get("endperiod");
        String startDate = (String) params.get("startdate");
        String endDate = (String) params.get("enddate");
        String isleave = (String) params.get("isleave");

        // 创建第一个 Map 对象
        Map<String, Object> firstBusiParamJson = new HashMap<>();
        firstBusiParamJson.put("pk_accountingbook", pkAccountingBook);
        firstBusiParamJson.put("pk_unit", new ArrayList<String>(){});
        firstBusiParamJson.put("multbusi", false);
        firstBusiParamJson.put("usesubjversion", "N");
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
// 格式化日期为 "yyyy-MM-dd" 格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String formattedDate = currentDate.format(formatter);

// 设置 versiondate 为当前日期
        firstBusiParamJson.put("versiondate", formattedDate);
        firstBusiParamJson.put("startlvl", "1");
        firstBusiParamJson.put("endlvl", "1");
        firstBusiParamJson.put("isleave", isleave);
        firstBusiParamJson.put("isoutacc", "N");
        firstBusiParamJson.put("startyear", startYear);
        firstBusiParamJson.put("endyear", endYear);
        firstBusiParamJson.put("startperiod", startPeriod);
        firstBusiParamJson.put("endperiod", endPeriod);
        firstBusiParamJson.put("startdate", startDate);
        firstBusiParamJson.put("enddate", endDate);
        firstBusiParamJson.put("includeuntally", "N");
        firstBusiParamJson.put("includeerror", "N");
        firstBusiParamJson.put("includeplcf", "Y");
        firstBusiParamJson.put("includerc", "N");
        firstBusiParamJson.put("pk_currtype", "本币");
        firstBusiParamJson.put("returncurr", "1");
        firstBusiParamJson.put("mutibook", "N");
        firstBusiParamJson.put("showzerooccur", "N");
        firstBusiParamJson.put("showzerobalanceoccur", "Y");
        firstBusiParamJson.put("sumbysubjtype", "N");
        firstBusiParamJson.put("showupsubj", "N");
        firstBusiParamJson.put("currplusacc", "Y");
        firstBusiParamJson.put("balanceori", "-1");
        firstBusiParamJson.put("twowaybalance", "N");
        firstBusiParamJson.put("istree", "Y");
        firstBusiParamJson.put("qryObjs", new ArrayList<String>(){});
        firstBusiParamJson.put("pk_accasoa", pkAccasoa);
        if(pkAccasoa.isEmpty() || pkAccasoa.get(0).equals("")){
            firstBusiParamJson.put("isleave", "N");
            firstBusiParamJson.put("pk_accasoa", new ArrayList<String>(){});
        }else{
            firstBusiParamJson.put("isleave", null);

        }
//        firstBusiParamJson.put("pk_accasoa", pkAccasoa);//1001A1100000000017SV

        Map<String, Object> firstSysParamJson = new HashMap<>();
        firstSysParamJson.put("busiaction", "科目辅助余额表-查询");
        firstSysParamJson.put("appcode", "20028003");
        firstSysParamJson.put("tabid", "");
        firstSysParamJson.put("ts", System.currentTimeMillis());
        firstSysParamJson.put("from", "");
        firstSysParamJson.put("pagecs", System.currentTimeMillis());

        // 创建第二个 Map 对象
        Map<String, Object> secondBusiParamJson = new HashMap<>();
        secondBusiParamJson.put("pk_accountingbook", pkAccountingBook);
        secondBusiParamJson.put("pk_unit",new ArrayList<String>());
        secondBusiParamJson.put("multbusi", false);
        secondBusiParamJson.put("usesubjversion", "N");
        secondBusiParamJson.put("versiondate", null);
        secondBusiParamJson.put("startlvl", "1");
        secondBusiParamJson.put("endlvl", "1");
        secondBusiParamJson.put("isleave", isleave);
        secondBusiParamJson.put("isoutacc", "N");
        secondBusiParamJson.put("startyear", startYear);
        secondBusiParamJson.put("endyear", endYear);
        secondBusiParamJson.put("startperiod", startPeriod);
        secondBusiParamJson.put("endperiod", endPeriod);
        secondBusiParamJson.put("startdate", startDate);
//        secondBusiParamJson.put("endtdate", endDate);
        secondBusiParamJson.put("enddate", endDate);
        secondBusiParamJson.put("includeuntally", "N");
        secondBusiParamJson.put("includeerror", "N");
        secondBusiParamJson.put("includeplcf", "Y");
        secondBusiParamJson.put("includerc", "N");
        secondBusiParamJson.put("pk_currtype", "本币");
        secondBusiParamJson.put("returncurr", "1");
        secondBusiParamJson.put("mutibook", "N");
        secondBusiParamJson.put("showzerooccur", "N");
        secondBusiParamJson.put("showzerobalanceoccur", "Y");
        secondBusiParamJson.put("currplusacc", "Y");
        secondBusiParamJson.put("sumbysubjtype", "N");
        secondBusiParamJson.put("balanceori", "-1");
        secondBusiParamJson.put("twowaybalance", "N");
        secondBusiParamJson.put("querybyperiod", true);
        secondBusiParamJson.put("pk_accasoa", pkAccasoa);//1001A1100000000017SV
        if(pkAccasoa.isEmpty() || pkAccasoa.get(0).equals("")){
            secondBusiParamJson.put("isleave", "N");
            secondBusiParamJson.put("pk_accasoa", new ArrayList<String>(){});
        }else{
            secondBusiParamJson.put("isleave", null);

        }
        secondBusiParamJson.put("appcode", "20023005");
        Map<String, Object> secondSysParamJson = new HashMap<>();
        secondSysParamJson.put("busiaction", "科目余额表-查询");
        secondSysParamJson.put("appcode", "20023005");
        secondSysParamJson.put("tabid", "");
        secondSysParamJson.put("ts", System.currentTimeMillis());
        secondSysParamJson.put("from", "");
        secondSysParamJson.put("pagecs", System.currentTimeMillis());
        Map<String, Object> paraMap = new HashMap<>();
        Map<String, Object> first = new HashMap<>();
        first.put("busiParamJson", firstBusiParamJson);
        first.put("sysParamJson", firstSysParamJson);
        Map<String, Object> second = new HashMap<>();
        second.put("busiParamJson2", secondBusiParamJson);
        second.put("sysParamJson2", secondSysParamJson);
        paraMap.put("first",firstBusiParamJson);
        paraMap.put("second",secondBusiParamJson);
        return paraMap;
    }
    private void setAppcode(Map<String, Object> paraMap) {
        String appcode = SessionContext.getInstance().getAppcode();
        if (appcode.startsWith("2002305010")) {
            appcode = (String)paraMap.get("pk_multicol");
        } else if (appcode.startsWith("2002308010")) {
            appcode = (String)paraMap.get("pk_report");
        }

        paraMap.put("appcode", appcode);
    }
}
