package com.bweb.controller;

import com.alibaba.excel.EasyExcel;
import com.bweb.excel.model.ExportTradeOrderModel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.UserCenter;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.ResponseMsgUtil;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.BsMer;
import com.hfkj.entity.BsTradeOrder;
import com.hfkj.entity.BsTradeSettle;
import com.hfkj.model.ResponseData;
import com.hfkj.model.TradeSettleBillsModel;
import com.hfkj.model.TradeSettleDetailBillsModel;
import com.hfkj.model.UserInfoModel;
import com.hfkj.service.*;
import com.hfkj.sysenum.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@Api(value = "交易订单")
@RequestMapping(value = "/tradeOrder")
public class BsTradeOrderController {

    private static Logger log = LoggerFactory.getLogger(BsTradeOrderController.class);

    @Resource
    private UserCenter userCenter;

    @Resource
    private BsTradeOrderService tradeOrderService;

    @Resource
    private BsTradeSettleService tradeSettleService;

    @Resource
    private BsTradeOrderRefundService tradeOrderRefundService;

    @Resource
    private BsMerService merService;

    @RequestMapping(value="/getOrderList",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询订单列表")
    public ResponseData getOrderList(@RequestParam(value = "salesmanId" , required = false) Long salesmanId,
                                     @RequestParam(value = "merId" , required = false) Long merId,
                                     @RequestParam(value = "merNo" , required = false) String merNo,
                                     @RequestParam(value = "merName" , required = false) String merName,
                                     @RequestParam(value = "merAbbreviate" , required = false) String merAbbreviate,
                                     @RequestParam(value = "companyId" , required = false) Long companyId,
                                     @RequestParam(value = "agentId" , required = false) Long agentId,
                                     @RequestParam(value = "storeId" , required = false) Long storeId,
                                     @RequestParam(value = "storeName" , required = false) String storeName,
                                     @RequestParam(value = "payMode" , required = false) String payMode,
                                     @RequestParam(value = "outTradeNo" , required = false) String outTradeNo,
                                     @RequestParam(value = "accTradeNo" , required = false) String accTradeNo,
                                     @RequestParam(value = "payTimeS" , required = false) Long payTimeS,
                                     @RequestParam(value = "payTimeE" , required = false) Long payTimeE,
                                     @RequestParam(value = "status" , required = false) Integer status,
                                     @RequestParam(value = "specialField" , required = false) String specialField,
                                     @RequestParam(value = "pageNum" , required = true) Integer pageNum,
                                     @RequestParam(value = "pageSize" , required = true) Integer pageSize) {
        try {
            Map<String, Object> param = new HashMap<>();
            UserInfoModel userModel = userCenter.getSessionModel(UserInfoModel.class);
            if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type0.getNumber())) {
                param.put("companyId", companyId);
                param.put("agentId", agentId);
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("merNo", merNo);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type1.getNumber())) {
                param.put("companyId", userModel.getBsCompany().getId());
                param.put("agentId", agentId);
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("merNo", merNo);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type2.getNumber())) {
                param.put("agentId", userModel.getAgent().getId());
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("merNo", merNo);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type3.getNumber())) {
                param.put("salesmanId", userModel.getSalesman().getId());
                param.put("merId", merId);
                param.put("merNo", merNo);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type4.getNumber())) {
                param.put("merId", userModel.getMer().getId());
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type5.getNumber())) {
                param.put("storeId", userModel.getStore().getId());
            }
            param.put("payMode", payMode);
            param.put("outTradeNo", outTradeNo);
            param.put("accTradeNo", accTradeNo);
            param.put("payTimeS", payTimeS);
            param.put("payTimeE", payTimeE);
            param.put("status", status);
            param.put("specialField", specialField);

            PageHelper.startPage(pageNum,pageSize);
            return ResponseMsgUtil.success(new PageInfo<>(tradeOrderService.getTradeOrderList(param)));

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/exportTradeOrder",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "导出交易订单")
    public ResponseData exportTradeOrder(@RequestParam(value = "salesmanId" , required = false) Long salesmanId,
                                         @RequestParam(value = "merId" , required = false) Long merId,
                                         @RequestParam(value = "merNo" , required = false) String merNo,
                                         @RequestParam(value = "merName" , required = false) String merName,
                                         @RequestParam(value = "merAbbreviate" , required = false) String merAbbreviate,
                                         @RequestParam(value = "companyId" , required = false) Long companyId,
                                         @RequestParam(value = "agentId" , required = false) Long agentId,
                                         @RequestParam(value = "storeId" , required = false) Long storeId,
                                         @RequestParam(value = "storeName" , required = false) String storeName,
                                         @RequestParam(value = "payMode" , required = false) String payMode,
                                         @RequestParam(value = "outTradeNo" , required = false) String outTradeNo,
                                         @RequestParam(value = "accTradeNo" , required = false) String accTradeNo,
                                         @RequestParam(value = "payTimeS" , required = false) Long payTimeS,
                                         @RequestParam(value = "payTimeE" , required = false) Long payTimeE,
                                         @RequestParam(value = "status" , required = false) Integer status,
                                         @RequestParam(value = "specialField" , required = false) String specialField
                                         ) {
        try {
            Map<String, Object> param = new HashMap<>();
            UserInfoModel userModel = userCenter.getSessionModel(UserInfoModel.class);
            if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type0.getNumber())) {
                param.put("companyId", companyId);
                param.put("agentId", agentId);
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("merNo", merNo);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type1.getNumber())) {
                param.put("companyId", userModel.getBsCompany().getId());
                param.put("agentId", agentId);
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("merNo", merNo);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type2.getNumber())) {
                param.put("agentId", userModel.getAgent().getId());
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("merNo", merNo);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type3.getNumber())) {
                param.put("salesmanId", userModel.getSalesman().getId());
                param.put("merId", merId);
                param.put("merNo", merNo);
                param.put("merName", merName);
                param.put("merAbbreviate", merAbbreviate);
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type4.getNumber())) {
                param.put("merId", userModel.getMer().getId());
                param.put("storeId", storeId);
                param.put("storeName", storeName);

            } else if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type5.getNumber())) {
                param.put("storeId", userModel.getStore().getId());
            }
            param.put("payMode", payMode);
            param.put("outTradeNo", outTradeNo);
            param.put("accTradeNo", accTradeNo);
            param.put("payTimeS", payTimeS);
            param.put("payTimeE", payTimeE);
            param.put("status", status);
            param.put("specialField", specialField);

            List<ExportTradeOrderModel> dataList = new ArrayList<>();
            ExportTradeOrderModel data;

            List<BsTradeOrder> tradeOrderList = tradeOrderService.getTradeOrderList(param);
            for (BsTradeOrder tradeOrder : tradeOrderList) {
                data = new ExportTradeOrderModel();
                data.setMerNo(tradeOrder.getMerNo());
                data.setMerName(tradeOrder.getMerName());
                data.setMerAbbreviate(tradeOrder.getMerAbbreviate());
                data.setStoreName(tradeOrder.getStoreName());
                data.setOutTradeNo(tradeOrder.getOutTradeNo());
                data.setAccTradeNo(tradeOrder.getAccTradeNo());
                data.setPayMode(TradeOrderPayModeEnum.getNameByCode(tradeOrder.getPayMode()).getName());
                data.setTradeAmount(tradeOrder.getTradeAmount());
                data.setStoreDiscountActualPrice(tradeOrder.getStoreDiscountActualPrice());
                data.setUserDiscountActualPrice(tradeOrder.getUserDiscountActualPrice());
                data.setTradeActualAmount(tradeOrder.getTradeActualAmount());
                data.setStatus(TradeOrderStatusEnum.getNameByNumber(tradeOrder.getStatus()).getName());
                data.setCreateType(TradeOrderCreateTypeEnum.getNameByCode(tradeOrder.getCreateType()).getName());
                data.setCreateTime(tradeOrder.getCreateTime());
                data.setPayTime(tradeOrder.getPayTime());
                data.setPlatformMerNo(tradeOrder.getPlatformMerNo());
                data.setSalesmanName(tradeOrder.getSalesmanName());
                data.setSpecialField(tradeOrder.getSpecialField());
                dataList.add(data);
            }

            String fileName = "/temporary/" + System.currentTimeMillis() + ".xlsx";
            EasyExcel.write(CommonSysConst.getSysConfig().getFilesystem() + fileName, ExportTradeOrderModel.class)
                    .sheet("交易订单")
                    .doWrite(dataList);
            return ResponseMsgUtil.success(fileName);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/getOrderByOutTradeOrder",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "根据交易订单号 查询订单信息")
    public ResponseData getOrderByOutTradeOrder(@RequestParam(value = "outTradeOrder" , required = true) String outTradeOrder) {
        try {
            // 查询订单
            BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(outTradeOrder);
            if (order == null) {
                log.error("configAccount error!","参数错误");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单");
            }
            Map<String, Object> param = new HashMap<>();
            param.put("order", order);
            param.put("orderRefund", tradeOrderRefundService.getRefundByOutTradeOrder(order.getOutTradeNo()));
            return ResponseMsgUtil.success(param);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }


    @RequestMapping(value="/queryCheckingDetail",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询交易对账详情")
    public ResponseData queryCheckingDetail(@RequestParam(value = "merNo" , required = true) String merNo,
                                            @RequestParam(value = "settleTimeS" , required = true) Long settleTimeS,
                                            @RequestParam(value = "settleTimeE" , required = true) Long settleTimeE,
                                            @RequestParam(value = "outTradeNo" , required = false) String outTradeNo,
                                            @RequestParam(value = "accTradeNo" , required = false) String accTradeNo,
                                            @RequestParam(value = "pageNum" , required = true) Integer pageNum,
                                            @RequestParam(value = "pageSize" , required = true) Integer pageSize) {
        try {
            // 查询商户
            BsMer mer = merService.getMer(merNo);
            if (mer == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
            }

            Map<String, Object> param = new HashMap<>();
            param.put("merNo", merNo);
            param.put("settleTimeS", settleTimeS);
            param.put("settleTimeE", settleTimeE);
            param.put("outTradeNo", outTradeNo);
            param.put("accTradeNo", accTradeNo);

            Map<String, Object> returnParam = new HashMap<>();
            PageHelper.startPage(pageNum,pageSize);
            // 交易结算
            returnParam.put("settleDetailList", new PageInfo<>(tradeSettleService.getTradeSettleList(param)));
            // 汇总
            Map<String, Object> tradeSettleCount = tradeSettleService.getTradeSettleCount(param);
            returnParam.put("totalTradeNum",  tradeSettleCount.get("tradeNum"));
            returnParam.put("totalTradeAmount", tradeSettleCount.get("tradeAmount"));
            returnParam.put("totalSettleAmount", tradeSettleCount.get("settleAmount"));
            returnParam.put("totalShdFeeAmount", tradeSettleCount.get("shdFeeAmount"));

            return ResponseMsgUtil.success(returnParam);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/exportCheckingDetail",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "导出查询交易对账详情")
    public ResponseData exportCheckingDetail(@RequestParam(value = "merNo" , required = true) String merNo,
                                            @RequestParam(value = "settleTimeS" , required = true) Long settleTimeS,
                                            @RequestParam(value = "settleTimeE" , required = true) Long settleTimeE,
                                            @RequestParam(value = "outTradeNo" , required = false) String outTradeNo,
                                            @RequestParam(value = "accTradeNo" , required = false) String accTradeNo) {
        try {
            // 查询商户
            BsMer mer = merService.getMer(merNo);
            if (mer == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
            }

            Map<String, Object> param = new HashMap<>();
            param.put("merNo", merNo);
            param.put("settleTimeS", settleTimeS);
            param.put("settleTimeE", settleTimeE);
            param.put("outTradeNo", outTradeNo);
            param.put("accTradeNo", accTradeNo);

            List<BsTradeSettle> list = tradeSettleService.getTradeSettleList(param);

            List<TradeSettleDetailBillsModel> billsModelList = new ArrayList<>();
            TradeSettleDetailBillsModel billsModel;

            Long serialNumber = 1L;
            for (BsTradeSettle tradeSettle : list) {
                billsModel = new TradeSettleDetailBillsModel();
                billsModel.setSerialNumber(serialNumber++);
                billsModel.setMerchantNo(mer.getMerNo());
                billsModel.setMerchantName(mer.getMerName());
                billsModel.setTradeTime(tradeSettle.getTradeTime());
                billsModel.setTradeAmount(tradeSettle.getTradeType().equals(TradeSettleTradeType.type2.getNumber())?"-"+tradeSettle.getTradeAmount():tradeSettle.getTradeAmount().toString());
                billsModel.setShdFeeAmt(tradeSettle.getTradeType().equals(TradeSettleTradeType.type2.getNumber())?"-"+tradeSettle.getShdFeeAmt():tradeSettle.getShdFeeAmt().toString());
                billsModel.setSettleAmount(tradeSettle.getTradeType().equals(TradeSettleTradeType.type2.getNumber())?"-"+tradeSettle.getSettleAmount():tradeSettle.getSettleAmount().toString());
                billsModel.setTradeType(TradeSettleTradeType.getNameByCode(tradeSettle.getTradeType()).getName());
                billsModel.setPayMode(TradeOrderPayModeEnum.getNameByCode(tradeSettle.getPayMode()).getName());
                billsModel.setOutTradeNo(tradeSettle.getOutTradeNo());
                billsModel.setAccTradeNo(tradeSettle.getAccTradeNo());
                billsModel.setSettleDate(DateUtil.date2String(tradeSettle.getSettleDate(), DateUtil.Y_M_D));
                billsModel.setFeeRate(tradeSettle.getFeeRate() + "%");
                billsModel.setOrgOutTradeNo(tradeSettle.getOrgOutTradeNo());
                billsModelList.add(billsModel);
            }

            String fileName = "/temporary/" + System.currentTimeMillis() + ".xlsx";
            EasyExcel.write(CommonSysConst.getSysConfig().getFilesystem() + fileName, TradeSettleDetailBillsModel.class)
                    .sheet("交易明细")
                    .doWrite(billsModelList);

            return ResponseMsgUtil.success(fileName);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/queryChecking",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询交易结算汇总")
    public ResponseData queryChecking(@RequestParam(value = "merNo" , required = true) String merNo,
                                      @RequestParam(value = "settleTimeS" , required = true) Long settleTimeS,
                                      @RequestParam(value = "settleTimeE" , required = true) Long settleTimeE) {
        try {
            // 查询商户
            BsMer mer = merService.getMer(merNo);
            if (mer == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
            }

            Map<String, Object> param = new HashMap<>();
            param.put("merNo", merNo);
            param.put("settleTimeS", settleTimeS);
            param.put("settleTimeE", settleTimeE);
            // 查询交易详情
            List<Map<String, Object>> mapList = tradeSettleService.getTradeSettleDayCount(param);

            int totalTradeNum = 0;
            BigDecimal totalTradeAmount = new BigDecimal("0");
            BigDecimal totalSettleAmount = new BigDecimal("0");
            BigDecimal totalShdFeeAmount = new BigDecimal("0");

            for (Map<String,Object> map : mapList) {
                map.put("merName", mer.getMerName());
                map.put("merAbbreviate", mer.getMerAbbreviate());
                totalTradeNum += MapUtils.getInteger(map, "tradeNum").intValue();
                totalTradeAmount = totalTradeAmount.add(new BigDecimal(MapUtils.getString(map, "tradeAmount")));
                totalSettleAmount = totalSettleAmount.add(new BigDecimal(MapUtils.getString(map, "settleAmount")));
                totalShdFeeAmount = totalShdFeeAmount.add(new BigDecimal(MapUtils.getString(map, "shdFeeAmount")));
            }

            Map<String, Object> returnParam = new HashMap<>();
            returnParam.put("merNo", mer.getMerNo());
            returnParam.put("merName", mer.getMerName());
            returnParam.put("totalTradeNum", totalTradeNum);
            returnParam.put("totalTradeAmount", totalTradeAmount);
            returnParam.put("totalSettleAmount", totalSettleAmount);
            returnParam.put("totalShdFeeAmount", totalShdFeeAmount);
            returnParam.put("settleList", mapList);
            return ResponseMsgUtil.success(returnParam);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/exportChecking",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "导出交易结算汇总")
    public ResponseData exportChecking(@RequestParam(value = "merNo" , required = true) String merNo,
                                       @RequestParam(value = "settleTimeS" , required = true) Long settleTimeS,
                                       @RequestParam(value = "settleTimeE" , required = true) Long settleTimeE) {
        try {
            // 查询商户
            BsMer mer = merService.getMer(merNo);
            if (mer == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
            }

            Map<String, Object> param = new HashMap<>();
            param.put("merNo", merNo);
            param.put("settleTimeS", settleTimeS);
            param.put("settleTimeE", settleTimeE);
            // 查询交易详情
            List<Map<String, Object>> list = tradeSettleService.getTradeSettleDayCount(param);

            List<TradeSettleBillsModel> settleBillsList = new ArrayList<>();
            TradeSettleBillsModel settleBills;
            for (Map<String,Object> map : list) {
                settleBills = new TradeSettleBillsModel();
                settleBills.setSettleDate(MapUtils.getString(map,"settleDay"));
                settleBills.setMerchantNo(MapUtils.getString(map,"merNo"));
                settleBills.setMerchantName(mer.getMerName());
                settleBills.setTradeNum(MapUtils.getLong(map,"tradeNum"));
                settleBills.setTradeAmount(MapUtils.getString(map,"tradeAmount"));
                settleBills.setShdFeeAmt(MapUtils.getString(map,"shdFeeAmount"));
                settleBills.setSettleAmount(MapUtils.getString(map,"settleAmount"));
                settleBillsList.add(settleBills);
            }
            String fileName = "/temporary/" + System.currentTimeMillis() + ".xlsx";
            EasyExcel.write(CommonSysConst.getSysConfig().getFilesystem() + fileName, TradeSettleBillsModel.class)
                    .sheet("交易汇总")
                    .doWrite(settleBillsList);

            return ResponseMsgUtil.success(fileName);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }
    }

}
