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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
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.ApiRes;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.db.entity.StatsTaskRecord;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

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

    @Autowired private StatsTradeService statsTradeService;
    @Autowired private StatsChannelService statsChannelService;
    @Autowired private StatsPayWayService statsPayWayService;
    @Autowired private StatsDeviceService statsDeviceService;
    @Autowired private StatsTaskRecordService statsTaskRecordService;
    @Autowired private PayOrderService payOrderService;

    /**
     * @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 ApiRes 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 = statsTradeService.selectMchStatsList(paramJSON, null);
                break;
            case CS.STATISTIC_TYPE.AGENT:
                // 服务商
                mapPage = statsTradeService.selectAgentStatsList(paramJSON, null);
                break;
            case CS.STATISTIC_TYPE.ISV:
                // 服务商
                mapPage = statsTradeService.selectIsvStatsList(paramJSON);
                break;
            case CS.STATISTIC_TYPE.CHANNEL:
                // 通道
                mapPage = statsChannelService.selectStatsList(paramJSON);
                break;
            case CS.STATISTIC_TYPE.TRANSACTION:
                // 交易报表
                mapPage = statsTradeService.selectTransactionStatsList(payOrder, paramJSON, null);
                break;
            case CS.STATISTIC_TYPE.STORE:
                // 门店
                getValStringRequired("mchNo");
                mapPage = statsTradeService.selectStoreStatsList(paramJSON);
                break;
            case CS.STATISTIC_TYPE.WAY_CODE:
                // 支付方式
                getValStringRequired("mchNo");
                mapPage = statsPayWayService.selectPayWayStatsList(paramJSON);
                break;
            case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
                // 支付类型
                getValStringRequired("mchNo");
                mapPage = statsPayWayService.selectWayCodeTypeStatsList(paramJSON);
                break;
            case CS.STATISTIC_TYPE.DEVICE:
                // 设备
                mapPage = statsDeviceService.selectStatsList(paramJSON, null);
                break;
            default:
                break;
        }
        // 解决hasnext不显示的问题
        mapPage.setCurrent(paramJSON.getIntValue("pageNumber"));
        mapPage.setSize(paramJSON.getIntValue("pageSize"));
        return ApiRes.page(mapPage);
    }

    /**
     * @author: zx
     * @date: 2022/5/23 17:15
     * @describe: 统计数据修复
     */
    @PreAuthorize("hasAuthority('ENT_STATISTIC_REPAIR')")
    @PostMapping
    public ApiRes repair() {
        String repairDate = getValString("repairDate");
        String mchNo = getValString("mchNo");

        Date beginRepairDate; // 开始日期
        Date endRepairDate; // 结束日期
        if (StringUtils.isBlank(repairDate)) {
            PayOrder payOrder = payOrderService.getOne(PayOrder.gw().orderByAsc(PayOrder::getCreatedAt).last("limit 1"));
            if (payOrder == null) {
                throw new BizException("无可修复订单数据");
            }
            beginRepairDate = DateUtil.beginOfDay(payOrder.getCreatedAt());
            endRepairDate = DateUtil.endOfDay(DateUtil.yesterday());
        }else {
            String[] repairDateSplit = repairDate.split(",");
            beginRepairDate = DateUtil.parseDate(repairDateSplit[0]);
            endRepairDate = DateUtil.parseDate(repairDateSplit[1]);
        }

        // 查询是否存在进行中的数据修复任务
        List<StatsTaskRecord> list = statsTaskRecordService.list(StatsTaskRecord.gw()
                .eq(StatsTaskRecord::getTaskType, StatsTaskRecord.TASK_TYPE_REPAIR)
                .eq(StatsTaskRecord::getState, StatsTaskRecord.TASK_STATE_ING)
        );
        if (CollUtil.isNotEmpty(list)) {
            throw new BizException("请等待上次数据修复任务完成，再执行新任务");
        }

        // 数据修复任务记录 初始化
        Long taskId = statsTaskRecordService.initTask(StatsTaskRecord.TASK_TYPE_REPAIR, beginRepairDate, endRepairDate);

        // 异步执行
        statsTaskRecordService.repairStats(taskId, beginRepairDate, endRepairDate, mchNo);

        return ApiRes.ok();
    }
}
