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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.StatsChannelService;
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.Arrays;
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 StatsTradeService statsTradeService;
    @Autowired private StatsChannelService statsChannelService;
    @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_ISV', 'ENT_STATISTIC_CHANNEL')")
    @RequestMapping(value="", method = RequestMethod.GET)
    public void list() {
        JSONObject paramJSON = getReqParamJSON();
        PayOrder payOrder = getObject(PayOrder.class);
        String method = getValStringRequired("method");
        String mchNo = null;
        Page<PayOrderCount> mapPage = new Page<>();
        switch (method) {
            case CS.STATISTIC_TYPE.MCH:
                // 商户
                // mapPage = payOrderService.countListByMch(payOrder, paramJSON, null);
                mapPage = statsTradeService.selectMchStatsList(paramJSON, null);
                exportExcel(mapPage, StatisticMchExportExcel.class, "商户统计");
                break;
            case CS.STATISTIC_TYPE.AGENT:
                // 服务商
                // mapPage = payOrderService.countListByAgent(payOrder, paramJSON, null);
                mapPage = statsTradeService.selectAgentStatsList(paramJSON, null);
                exportExcel(mapPage, StatisticAgentExportExcel.class, "服务商统计");
                break;
            case CS.STATISTIC_TYPE.ISV:
                // 服务商
                // mapPage = payOrderService.countListByIsv(payOrder, paramJSON);
                mapPage = statsTradeService.selectIsvStatsList(paramJSON);
                exportExcel(mapPage, StatisticIsvExportExcel.class, "服务商统计");
                break;
            case CS.STATISTIC_TYPE.CHANNEL:
                // 通道
                // mapPage = payOrderService.countListByChannel(payOrder, paramJSON);
                mapPage = statsChannelService.selectStatsList(paramJSON);
                exportExcel(mapPage, StatisticChannelExportExcel.class, "通道统计");
                break;
            case CS.STATISTIC_TYPE.TRANSACTION:
                // 交易报表
                // mapPage = payOrderService.countListByTransaction(payOrder, paramJSON, null);
                mapPage = statsTradeService.selectTransactionStatsList(payOrder, paramJSON, null);
                exportExcel(mapPage, StatisticTransactionExportExcel.class, "交易报表");
                break;
            case CS.STATISTIC_TYPE.STORE:
                // 门店
                getValStringRequired("mchNo");
                // payOrder.setMchNo(mchNo);
                // mapPage = payOrderService.countListByStore(payOrder, paramJSON);
                mapPage = statsTradeService.selectStoreStatsList(paramJSON);
                exportExcel(mapPage, StatisticStoreExportExcel.class, "门店统计");
                break;
            case CS.STATISTIC_TYPE.WAY_CODE:
                // 支付方式
                getValStringRequired("mchNo");
                // payOrder.setMchNo(mchNo);
                // mapPage = payOrderService.countListByWayCode(payOrder, paramJSON);
                mapPage = statsPayWayService.selectPayWayStatsList(paramJSON);
                exportExcel(mapPage, StatisticWayCodeExportExcel.class, "支付方式统计");
                break;
            case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
                // 支付类型
                getValStringRequired("mchNo");
                // payOrder.setMchNo(mchNo);
                // mapPage = payOrderService.countListByWayCodeType(payOrder, paramJSON);
                mapPage = statsPayWayService.selectWayCodeTypeStatsList(paramJSON);
                exportExcel(mapPage, StatisticWayCodeTypeExportExcel.class, "支付类型统计");
                break;
            case CS.STATISTIC_TYPE.DEVICE:
                // 通道统计
                // mapPage = payOrderService.countListByDevice(payOrder, paramJSON, null);
                mapPage = statsDeviceService.selectStatsList(paramJSON, null);
                exportExcel(mapPage, 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 {
                // 查询服务商所有下级
                allAgentNoList = agentInfoService.queryAllSubAgentNo(payOrder.getAgentNo());
            }
        }
        return allAgentNoList;
    }

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

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

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

                newList.add(resItem);
            });

            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("导出订单失败！");
        }

    }

}
