package com.saye.hospitalgd.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.saye.hospitalgd.commons.date.DateDUtil;
import com.saye.hospitalgd.commons.string.StringDUtil;
import com.saye.hospitalgd.model.Dicinfo;
import com.saye.hospitalgd.service.BankbillHistoryService;
import com.saye.hospitalgd.service.TransactionDetailService;
import com.saye.hospitalgd.service.system.DicinfoService;
import com.saye.hospitalgd.service.system.ServiceParamsService;
import com.saye.hospitalgd.service.FinancialReconciliation.TenpaySummaryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author thuang
 * @version 1.0
 * @description: 支付统计
 * @date 2021/9/18 16:32
 */
@Controller
@Slf4j
@RequestMapping("/paymentStatistics")
@Api(tags = "支付统计相关接口")
public class PaymentStatisticsController {

    @Autowired
    private DicinfoService dicinfoService;

    @Autowired
    private BankbillHistoryService bankbillHistoryService;

    @Autowired
    private TransactionDetailService transactionDetailService;

    @Autowired
    private ServiceParamsService serviceParamsService;

    @Autowired
    private TenpaySummaryService tenpaySummaryService;

    @RequestMapping("/toPaymentStatistics")
    public String toPaymentStatistics(ModelMap modelMap) {
        return "paymentStatistics/paymentStatistics";
    }

    /**
     * @description: 查询支付统计页面数据
     * @author thuang
     * @date 2021/10/22 16:55
     * @version 1.0
     */
    @PostMapping("/findpaymentStatisticsData")
    @ResponseBody
    @ApiOperation(value = "查询支付统计页面数据")
    public HashMap<Object, Object> findpaymentStatisticsData(@RequestBody HashMap<Object, Object> map) {
        HashMap<Object, Object> responseMap = new HashMap<Object, Object>();
        String errCode = "0";
        String errMsg = "";

        try {
            String startTime = StringDUtil.changeNullToEmpty(map.get("startTime"));
            String endTime = StringDUtil.changeNullToEmpty(map.get("endTime"));

            List<String> betweenDate = DateDUtil.getBetweenDate(startTime, endTime);

            // 查询字典表支付方式 - 使用THIRD_PAY三方支付方式字典
            List<Dicinfo> pay_type = dicinfoService.findDicinfoTreeNodeList("THIRD_PAY");
            HashMap<String, String> payMethodMap = new HashMap<>();
            for (Dicinfo dicinfo : pay_type) {
                String dicname = dicinfo.getDicname();
                String dicvalue = dicinfo.getDicvalue();
                
                // 根据三方支付字典配置映射支付方式
                payMethodMap.put(dicvalue, dicname);
            }

            // 先组织好map
            LinkedHashMap<String, LinkedHashMap<String, String>> numMap = new LinkedHashMap<>();
            LinkedHashMap<String, LinkedHashMap<String, String>> moneyMap = new LinkedHashMap<>();
            LinkedHashMap<String, String> addMap = new LinkedHashMap<>();
            SimpleDateFormat sdf = new SimpleDateFormat("MM/dd");
            List<String> betweenDateList = new ArrayList<>();
            for (String s : betweenDate) {
                addMap.put(s, "0");

                Date date = DateDUtil.strToDate(DateDUtil.yyyy_MM_dd, s);
                betweenDateList.add(sdf.format(date));
            }

            // 根据THIRD_PAY三方支付字典初始化统计分类
            numMap.put("微信支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});
            numMap.put("刷卡支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});
            numMap.put("支付宝支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});
            numMap.put("其他支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});

            moneyMap.put("微信支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});
            moneyMap.put("刷卡支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});
            moneyMap.put("支付宝支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});
            moneyMap.put("其他支付", new LinkedHashMap<String, String>() {{
                putAll(addMap);
            }});

            // 返回格式化后的日期数组
            responseMap.put("betweenDate", betweenDateList);

            List<HashMap<Object, Object>> thirdNumList = bankbillHistoryService.findBankBillNumByTime(map);

            for (HashMap<Object, Object> hashMap : thirdNumList) {
                String num1 = StringDUtil.changeNullToEmpty(hashMap.get("NUM"));
                String c_jyrq = StringDUtil.changeNullToEmpty(hashMap.get("C_JYRQ"));
                String c_zffs = StringDUtil.changeNullToEmpty(hashMap.get("C_ZFFS"));
                String str_zffs = "";
                String s = payMethodMap.get(c_zffs);
                if (s == null) {
                    str_zffs = "其他支付";
                } else {
                    str_zffs = s;
                }
                LinkedHashMap<String, String> zffsMap = numMap.get(str_zffs);
                if (zffsMap != null) {
                    String countNum = zffsMap.get(c_jyrq);
                    // 安全处理countNum，如果为null或空字符串则默认为"0"
                    if (countNum == null || countNum.isEmpty()) {
                        countNum = "0";
                    }
                    countNum = new BigDecimal(countNum).add(new BigDecimal(num1)).toString();
                    zffsMap.put(c_jyrq, countNum);
                }
            }

            // 将linkedHashMap转为list<hashMap<>> hashMap 中 name 支付方式，data list集合 内容为计算的数据
            List<HashMap<String, Object>> resultNumList = new ArrayList<>();
            for (String key : numMap.keySet()) {
                LinkedHashMap<String, String> linkedHashMap = numMap.get(key);
                List<String> newList = new ArrayList<>();
                for (String key2 : linkedHashMap.keySet()) {
                    String s = linkedHashMap.get(key2);
                    newList.add(s);
                }
                HashMap<String, Object> newMap = new HashMap<>();
                newMap.put("name", key);
                newMap.put("data", newList);
                resultNumList.add(newMap);
            }
            responseMap.put("resultNumList", resultNumList);


            List<HashMap<Object, Object>> thirdMoneyList = bankbillHistoryService.findBankBillMoneyByTime(map);
            for (HashMap<Object, Object> hashMap : thirdMoneyList) {
                String money = StringDUtil.changeNullToEmpty(hashMap.get("MONEY"));
                String c_jyrq = StringDUtil.changeNullToEmpty(hashMap.get("C_JYRQ"));
                String c_zffs = StringDUtil.changeNullToEmpty(hashMap.get("C_ZFFS"));
                String str_zffs = "";
                String s = payMethodMap.get(c_zffs);
                if (s == null) {
                    str_zffs = "其他支付";
                } else {
                    str_zffs = s;
                }
                LinkedHashMap<String, String> zffsMap = moneyMap.get(str_zffs);
                if (zffsMap != null) {
                    String countNum = zffsMap.get(c_jyrq);
                    // 安全处理countNum，如果为null或空字符串则默认为"0"
                    if (countNum == null || countNum.isEmpty()) {
                        countNum = "0";
                    }
                    countNum = new BigDecimal(countNum).add(new BigDecimal(money)).toString();
                    zffsMap.put(c_jyrq, countNum);
                }
            }

            // 将linkedHashMap转为list<hashMap<>> hashMap 中 name 支付方式，data list集合 内容为计算的数据
            List<HashMap<String, Object>> resultMoneyList = new ArrayList<>();
            for (String key : moneyMap.keySet()) {
                LinkedHashMap<String, String> linkedHashMap = moneyMap.get(key);
                List<String> newList = new ArrayList<>();
                for (String key2 : linkedHashMap.keySet()) {
                    String s = linkedHashMap.get(key2);
                    newList.add(s);
                }
                HashMap<String, Object> newMap = new HashMap<>();
                newMap.put("name", key);
                newMap.put("data", newList);
                resultMoneyList.add(newMap);
            }
            responseMap.put("resultMoneyList", resultMoneyList);

        } catch (Exception e) {
            e.printStackTrace();
            errCode = "999";
            errMsg = "查询统计数据失败，原因：" + e.getMessage();
        }

        responseMap.put("errCode", errCode);
        responseMap.put("errMsg", errMsg);
        return responseMap;
    }

    /**
     * @description: 对账汇总统计
     * @author thuang
     * @date 2021/12/1 14:53
     * @version 1.0
     */
    @RequestMapping("/toSummary")
    @ApiOperation("对账汇总统计")
    public String toPrint(HttpServletRequest request, ModelMap modelMap) {

        String trade_date = StringDUtil.changeNullToEmpty(request.getParameter("trade_date"));


        if ("".equals(trade_date)) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());

            calendar.add(Calendar.DATE, -1);
            Date startDate = calendar.getTime();

            String startTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd, startDate);
            String endTime = DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd);

            modelMap.addAttribute("startTime", startTime);
            modelMap.addAttribute("endTime", endTime);
        } else {
            modelMap.addAttribute("startTime", trade_date);
            modelMap.addAttribute("endTime", trade_date);
            modelMap.addAttribute("isClick", "1");
        }

        List<HashMap<Object, Object>> serviceParams = serviceParamsService.findParamValByParamCode("dzhz_table_name");
        String dzhz_table_name = StringDUtil.changeNullToEmpty(serviceParams.get(0).get("PARAM_VAL"));
        modelMap.addAttribute("table_name", dzhz_table_name);

        return "paymentStatistics/summary";
    }

    @RequestMapping("/toTenpaySummary")
    @ApiOperation("财付通汇款汇总表")
    public String toTenpaySummary(HttpServletRequest request, ModelMap modelMap) {
        String trade_date = StringDUtil.changeNullToEmpty(request.getParameter("trade_date"));
        if ("".equals(trade_date)) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DATE, -1);
            Date startDate = calendar.getTime();
            String startTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd, startDate);
            String endTime = DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd);
            modelMap.addAttribute("startTime", startTime);
            modelMap.addAttribute("endTime", endTime);
        } else {
            modelMap.addAttribute("startTime", trade_date);
            modelMap.addAttribute("endTime", trade_date);
            modelMap.addAttribute("isClick", "1");
        }
        return "paymentStatistics/tenpaySummary";
    }

    /**
     * @description: 查询汇总表数据
     * @author thuang
     * @date 2021/12/3 16:29
     * @version 1.0
     */
    @PostMapping("/findSummaryData")
    @ResponseBody
    @ApiOperation("查询汇总表数据")
    public HashMap<Object, Object> findSummaryData(@RequestBody HashMap<Object, Object> map) {
        HashMap<Object, Object> resultMap = new HashMap<>();
        String errCode = "0";
        String errMsg = "";

        try {

            map.put("is_active", "1");
            List<HashMap<Object, Object>> list = transactionDetailService.findHisAndThirdJoinData(map);

            // his需要统计（自定义PayType编码）: 1微信支付 2聚合支付 3军保支付 4其他 5现金支付
            // 三方需要统计 1_1微信支付 1_2支付宝支付 云闪付支付 其他支付 2银行卡支付 3掌医支付 4现金支付 5其他

            HashMap<Object, Object> hisMoneyData = new HashMap<>();
            hisMoneyData.put("1", "0"); // 微信支付
            hisMoneyData.put("2", "0"); // 聚合支付
            hisMoneyData.put("3", "0"); // 军保支付
            hisMoneyData.put("4", "0"); // 其他
            hisMoneyData.put("5", "0"); // 现金支付

            HashMap<Object, Object> thirdMoneyData = new HashMap<>();
            thirdMoneyData.put("1_1", "0");
            thirdMoneyData.put("1_2", "0");
            thirdMoneyData.put("1_3", "0");
            thirdMoneyData.put("1_4", "0");
            thirdMoneyData.put("2", "0");
            thirdMoneyData.put("3", "0");
            thirdMoneyData.put("4", "0");
            thirdMoneyData.put("5", "0");

            HashMap<Object, Object> hisNumData = new HashMap<>();
            hisNumData.put("1", "0"); // 微信支付
            hisNumData.put("2", "0"); // 聚合支付
            hisNumData.put("3", "0"); // 军保支付
            hisNumData.put("4", "0"); // 其他
            hisNumData.put("5", "0"); // 现金支付


            HashMap<Object, Object> thirdNumData = new HashMap<>();
            thirdNumData.put("1_1", "0");
            thirdNumData.put("1_2", "0");
            thirdNumData.put("1_3", "0");
            thirdNumData.put("1_4", "0");
            thirdNumData.put("2", "0");
            thirdNumData.put("3", "0");
            thirdNumData.put("4", "0");
            thirdNumData.put("5", "0");

            for (int i = 0; i < list.size(); i++) {
                HashMap<Object, Object> hashMap = list.get(i);

                String i_jyje = StringDUtil.changeNullToEmpty(hashMap.get("I_JYJE")).trim();
                String i_zffs = StringDUtil.changeNullToEmpty(hashMap.get("I_JYQD")).trim();

                String amount = StringDUtil.changeNullToEmpty(hashMap.get("AMOUNT")).trim();
                String paytype = StringDUtil.changeNullToEmpty(hashMap.get("PAYTYPE")).trim();
                
                // 数据核准：确保PayType在预定义范围内
                if (!hisMoneyData.containsKey(paytype)) {
                    log.warn("发现未预定义的PayType: [{}], 数据: {}, 已归类为其他支付方式", paytype, hashMap);
                    paytype = "4"; // 归类为其他支付方式
                }
                
                // 数据核准：确保I_JYQD在预定义范围内
                if (!thirdMoneyData.containsKey(i_zffs)) {
                    log.warn("发现未预定义的I_JYQD: [{}], 数据: {}, 已归类为其他支付方式", i_zffs, hashMap);
                    i_zffs = "5"; // 归类为其他支付方式
                }

                // 如果银行端金额不为空

                if (StrUtil.isNotBlank(i_jyje)) {
                    try {
                        log.info("处理银行端数据: i_zffs={}, i_jyje={}", i_zffs, i_jyje);
                        
                        // 验证金额格式
                        BigDecimal transAmount = new BigDecimal(i_jyje);
                        if (transAmount.compareTo(BigDecimal.ZERO) < 0) {
                            log.warn("发现负数金额: i_jyje={}, 数据: {}", i_jyje, hashMap);
                        }
                        
                        // 安全获取当前金额，如果为null则默认为BigDecimal.ZERO
                        BigDecimal money = Convert.toBigDecimal(thirdMoneyData.get(i_zffs), BigDecimal.ZERO);
                        money = money.add(transAmount);
                        thirdMoneyData.put(i_zffs, money.toString());

                        // 安全获取当前数量，如果为null或空字符串则默认为"0"
                        String currentNumStr = StringDUtil.changeNullToEmpty(thirdNumData.get(i_zffs));
                        if (currentNumStr.isEmpty()) {
                            currentNumStr = "0";
                        }
                        
                        int num = Integer.parseInt(currentNumStr);
                        num++;
                        thirdNumData.put(i_zffs, num + "");
                        
                    } catch (NumberFormatException e) {
                        log.error("银行端金额格式错误: i_jyje=[{}], 数据: {}, 错误: {}", i_jyje, hashMap, e.getMessage());
                    }
                }

                // 如果his端金额不为空

                if (StrUtil.isNotBlank(amount)) {
                    try {
                        log.info("处理HIS端数据: paytype={}, amount={}", paytype, amount);
                        
                        // 验证金额格式
                        BigDecimal transAmount = new BigDecimal(amount);
                        if (transAmount.compareTo(BigDecimal.ZERO) < 0) {
                            log.warn("发现负数金额: amount={}, 数据: {}", amount, hashMap);
                        }
                        
                        // 安全获取当前金额，如果为null或空字符串则默认为"0"
                        String currentMoneyStr = StringDUtil.changeNullToEmpty(hisMoneyData.get(paytype));
                        if (currentMoneyStr.isEmpty()) {
                            currentMoneyStr = "0";
                        }
                        
                        BigDecimal money = new BigDecimal(currentMoneyStr);
                        money = money.add(transAmount);
                        hisMoneyData.put(paytype, money.toString());

                        // 安全获取当前数量，如果为null或空字符串则默认为"0"
                        String currentNumStr = StringDUtil.changeNullToEmpty(hisNumData.get(paytype));
                        if (currentNumStr.isEmpty()) {
                            currentNumStr = "0";
                        }
                        
                        int num = Integer.parseInt(currentNumStr);
                        num++;
                        hisNumData.put(paytype, num + "");
                        
                    } catch (NumberFormatException e) {
                        log.error("HIS端金额格式错误: amount=[{}], 数据: {}, 错误: {}", amount, hashMap, e.getMessage());
                    }
                }
            }

            resultMap.put("hisMoneyData", hisMoneyData);
            resultMap.put("thirdMoneyData", thirdMoneyData);
            resultMap.put("hisNumData", hisNumData);
            resultMap.put("thirdNumData", thirdNumData);
        } catch (Exception e) {
            e.printStackTrace();
            errCode = "999";
            errMsg = "查询对账汇总表信息失败，原因：" + e.getMessage();
        }
        resultMap.put("errCode", errCode);
        resultMap.put("errMsg", errMsg);
        return resultMap;
    }

    @RequestMapping("/findTenpaySummary")
    @ResponseBody
    @ApiOperation("查询财付通汇款汇总数据")
    public HashMap<Object, Object> findTenpaySummary(String startTime, String endTime) {
        HashMap<Object, Object> response = new HashMap<>();
        try {
            // 如果未选择日期，则默认查询昨日到今日，避免无条件查全量
            if ((startTime == null || "".equals(startTime.trim())) && (endTime == null || "".equals(endTime.trim()))) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -1);
                Date startDate = calendar.getTime();
                startTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd, startDate);
                endTime = DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd);
            }

            HashMap<Object, Object> map = new HashMap<>();
            map.put("startTime", startTime);
            map.put("endTime", endTime);
            List<HashMap<Object, Object>> bankList = tenpaySummaryService.findTenpayBankSummary(map);
            List<HashMap<Object, Object>> hisList = tenpaySummaryService.findTenpayHisSummary(map);
            response.put("code", 0);
            response.put("msg", "OK");
            response.put("bankData", bankList);
            response.put("hisData", hisList);
        } catch (Exception e) {
            response.put("code", 1);
            response.put("msg", e.getMessage());
        }
        return response;
    }

}
