package com.jeequan.jeepay.agent.ctrl.statistics;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.export.statistic.*;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.StatsDeviceService;
import com.jeequan.jeepay.service.impl.StatsPayWayService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;

/**
 * 统计列表接口
 *
 * @author xiaoyu
 *
 * @date 2022/5/23 16:52
 */
@Slf4j
@RestController
@RequestMapping("/api/statistic/export")
public class ExportExcelStatisticController extends CommonCtrl {

    @Autowired private AgentInfoService agentInfoService;
    @Autowired private StatsTradeService statsTradeService;
    @Autowired private StatsPayWayService statsPayWayService;
    @Autowired private StatsDeviceService statsDeviceService;

    /**
     * @author: xiaoyu
     * @date: 2022/5/23 17:15
     * @describe: 统计列表
     */
    @PreAuthorize("hasAnyAuthority('ENT_STATISTIC_TRANSACTION', 'ENT_STATISTIC_MCH', 'ENT_STATISTIC_MCH_STORE', 'ENT_STATISTIC_MCH_WAY', 'ENT_STATISTIC_MCH_TYPE', 'ENT_STATISTIC_AGENT', 'ENT_STATISTIC_CHANNEL')")
    @RequestMapping(value="", method = RequestMethod.GET)
    public void list() {
        JSONObject paramJSON = getReqParamJSON();
        PayOrder payOrder = getObject(PayOrder.class);

        List<String> agentSubList = null;

        if (StringUtils.isEmpty(payOrder.getAgentNo())) {
            // 查询服务商所有下级
            agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
        }
        String method = getValStringRequired("method");
        String mchNo = null;
        Page<PayOrderCount> countPage = null;
        switch (method) {
            case CS.STATISTIC_TYPE.MCH:
                // 商户
                countPage = statsTradeService.selectMchStatsList(paramJSON, agentSubList);
                exportExcel(countPage, StatisticMchExportExcel.class, "商户统计");
                break;
            case CS.STATISTIC_TYPE.AGENT:
                // 服务商
                countPage = statsTradeService.selectAgentStatsList(paramJSON, agentSubList);
                exportExcel(countPage, StatisticAgentExportExcel.class, "服务商统计");
                break;
            case CS.STATISTIC_TYPE.TRANSACTION:
                // 交易报表
                // mapPage = payOrderService.countListByTransaction(payOrder, paramJSON, agentSubList);
                countPage = statsTradeService.selectTransactionStatsList(payOrder, paramJSON, agentSubList);
                exportExcel(countPage, StatisticTransactionExportExcel.class, "交易报表");
                break;
            case CS.STATISTIC_TYPE.STORE:
                // 门店
                getValStringRequired("mchNo");
                countPage = statsTradeService.selectStoreStatsList(paramJSON);
                exportExcel(countPage, StatisticStoreExportExcel.class, "门店统计");
                break;
            case CS.STATISTIC_TYPE.WAY_CODE:
                // 支付方式
                getValStringRequired("mchNo");
                countPage = statsPayWayService.selectPayWayStatsList(paramJSON);
                exportExcel(countPage, StatisticWayCodeExportExcel.class, "支付方式统计");
                break;
            case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
                // 支付类型
                getValStringRequired("mchNo");
                countPage = statsPayWayService.selectWayCodeTypeStatsList(paramJSON);
                exportExcel(countPage, StatisticWayCodeTypeExportExcel.class, "支付类型统计");
                break;
            case CS.STATISTIC_TYPE.DEVICE:
                // 设备统计
                countPage = statsDeviceService.selectStatsList(paramJSON, agentSubList);
                exportExcel(countPage, StatisticDeviceExportExcel.class, "设备统计");
                break;
            default:
                break;
        }
    }

    public List<String> getAgentSubList(JSONObject paramJSON, PayOrder payOrder) {
        List<String> allAgentNoList = null;
        if (StringUtils.isNotEmpty(payOrder.getAgentNo())) {
            Boolean onlyOne = paramJSON.getBoolean("onlyOne");
//            if (onlyOne) {
//                // 仅查询单个服务商
//                allAgentNoList = Arrays.asList(payOrder.getAgentNo());
//            } else if ("onlyOne".equals(payOrder.getAgentNo())) {
//                allAgentNoList = Arrays.asList(getCurrentAgentNo());
//            } else {
//                // 查询服务商所有下级
//                allAgentNoList = agentInfoService.queryAllSubAgentNo(payOrder.getAgentNo());
//            }
        }
        return allAgentNoList;
    }

    /** 通用导出类 **/
    public void exportExcel(Page<PayOrderCount> countPage, Class clazz, String title) {
        try {

            List<JSONObject> newList = new LinkedList<>();
            countPage.getRecords().stream().forEach(record -> {
                JSONObject itemData = (JSONObject) JSONObject.toJSON(record);
                // 交易金额转换
                BigDecimal totalSuccAmt = new BigDecimal(record.getTotalSuccAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                itemData.put("allAmount", totalSuccAmt);
                // 实收金额转换
                BigDecimal totalFinalAmt = BigDecimal.valueOf(record.getTotalFinalAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                itemData.put("payAmount", totalFinalAmt);
                // 退款金额转换
                BigDecimal refundAmount = BigDecimal.valueOf(record.getTotalRefundAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                itemData.put("refundAmount", refundAmount);
                //手续费
                if (record.getTotalFeeAmt() != null){
                    BigDecimal totalfeeamt = BigDecimal.valueOf(record.getTotalFeeAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    itemData.put("totalFeeAmt", totalfeeamt);
                }
                //手续费回退
                if (record.getTotalRefundFeeAmt() != null){
                    BigDecimal totalReFeeAmt= BigDecimal.valueOf(record.getTotalRefundFeeAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    itemData.put("totalRefundFeeAmt", totalReFeeAmt);
                }
                // 成功率
                itemData.put("round", record.getSuccRate() + "%");

                if (StringUtils.isNotBlank(record.getDeviceType())) {
                    itemData.put("deviceType", PayOrder.DEVICE_TYPE_MAP.get(record.getDeviceType()));
                }

                newList.add(itemData);
            });

            List<T> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), clazz);
            // excel输出
            ExcelUtil.exportExcel(linkedList, title, title, clazz, title, response);
        }catch (Exception e) {
            logger.error("导出excel失败", e);
            throw new BizException("导出订单失败！");
        }

    }

}
