package com.web.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.security.UserCenter;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.entity.HighChildOrder;
import com.hai.entity.HighOrder;
import com.hai.entity.HighOrderRefund;
import com.hai.model.HighUserModel;
import com.hai.model.ResponseData;
import com.hai.model.UserInfoModel;
import com.hai.order.model.ExportOrderRefundModel;
import com.hai.order.service.OrderRefundService;
import com.hai.order.service.OrderService;
import com.hai.order.type.*;
import com.web.config.SysConst;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "")
@Api(value = "订单退款业务")
public class OrderRefundController {

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

    @Resource
    private OrderService orderService;

    @Resource
    private OrderRefundService orderRefundService;

    @Resource
    private UserCenter userCenter;


    @RequestMapping(value="/refund",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "交易订单退款")
    public ResponseData refundOrder(@RequestBody JSONObject body) {
        try {
            UserInfoModel userInfoModel = userCenter.getSessionModel(UserInfoModel.class);
            if (userInfoModel == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.SEC_USER_EXPIRED, "");
            }
            if (body == null || StringUtils.isBlank(body.getString("orderNo"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单");
            }
            // 查询订单
            HighOrder order = orderService.getOrderDetailByNo(body.getString("orderNo"));
            if (order == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单");
            }
            if (!order.getOrderStatus().equals(OrderStatus.STATUS2.getNumber())
                    && !order.getOrderStatus().equals(OrderStatus.STATUS3.getNumber())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单状态错误");
            }
            orderService.refundOrder(order,
                    body.getString("remarks"),
                    OrderRefundOpUserType.TYPE2,
                    userInfoModel.getSecUser().getId(),
                    userInfoModel.getSecUser().getUserName()
            );

            return ResponseMsgUtil.success("退款成功");

        } catch (Exception e) {
            log.error("OrderController -> refundOrder() error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/refundChild",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "子订单退款")
    public ResponseData refundChild(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("childOrderNo"))
                    || body.getInteger("refundGoodsNum") == null
            ) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单");
            }
            UserInfoModel userInfoModel = userCenter.getSessionModel(UserInfoModel.class);
            if (userInfoModel == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.SEC_USER_EXPIRED, "");
            }
            // 查询订单编号
            HighChildOrder orderChild = orderService.getChildOrderByNo(body.getString("childOrderNo"));
            if (orderChild == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单编号");
            }
            if (!orderChild.getChildOrderStatus().equals(OrderChildStatus.STATUS2.getNumber())
                    && !orderChild.getChildOrderStatus().equals(OrderChildStatus.STATUS3.getNumber())){
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "子订单状态错误");
            }
            HighOrder order = orderService.getOrderDetailByNo(orderChild.getOrderNo());
            if (order == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "交易订单不存在");
            }
            orderService.refundChildOrder(
                    order, body.getString("childOrderNo"),
                    body.getInteger("refundGoodsNum"),
                    body.getString("remarks"),
                    OrderRefundOpUserType.TYPE2,
                    userInfoModel.getSecUser().getId(),
                    userInfoModel.getSecUser().getUserName()
            );

            return ResponseMsgUtil.success("退款成功");

        } catch (Exception e) {
            log.error("OrderController -> refundOrderChild() error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/getRefundByRefundNo",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "根据退款订单号，查询退款详情")
    public ResponseData getRefundByRefundNo(@RequestParam(name = "refundOrderNo", required = true) String refundOrderNo) {
        try {
            HighUserModel userModel = userCenter.getSessionModel(HighUserModel.class);
            if (userModel == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.USE_VISIT_ILLEGAL, "");
            }
            return ResponseMsgUtil.success(orderRefundService.getRefundByRefundNo(refundOrderNo));

        } catch (Exception e) {
            log.error("OrderController -> getRefundByRefundNo() error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/getUserRefundList",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "获取用户退款列表")
    public ResponseData getUserRefundList(@RequestParam(name = "orderNo", required = false) String orderNo,
                                          @RequestParam(name = "orderChildNo", required = false) String orderChildNo,
                                          @RequestParam(name = "goodsType", required = false) Integer goodsType,
                                          @RequestParam(name = "status", required = false) Integer status,
                                          @RequestParam(name = "pageNum", required = true) Integer pageNum,
                                          @RequestParam(name = "pageSize", required = true) Integer pageSize) {
        try {
            HighUserModel userModel = userCenter.getSessionModel(HighUserModel.class);
            if (userModel == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.USE_VISIT_ILLEGAL, "");
            }
            Map<String, Object> param = new HashMap<>();
            param.put("memId", userModel.getHighUser().getId());
            param.put("orderNo", orderNo);
            param.put("orderChildNo", orderChildNo);
            param.put("goodsType", goodsType);
            param.put("status", status);

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

        } catch (Exception e) {
            log.error("OrderRefundController -> getUserRefundList() error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/getRefundList",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "获取退款列表")
    public ResponseData getRefundList(@RequestParam(name = "orderNo", required = false) String orderNo,
                                      @RequestParam(name = "orderChildNo", required = false) String orderChildNo,
                                      @RequestParam(name = "refundOrderNo", required = false) String refundOrderNo,
                                      @RequestParam(name = "memPhone", required = false) String memPhone,
                                      @RequestParam(name = "goodsType", required = false) Integer goodsType,
                                      @RequestParam(name = "goodsName", required = false) String goodsName,
                                      @RequestParam(name = "status", required = false) Integer status,
                                      @RequestParam(name = "createTimeS", required = false) Long createTimeS,
                                      @RequestParam(name = "createTimeE", required = false) Long createTimeE,
                                      @RequestParam(name = "refundTimeS", required = false) Long refundTimeS,
                                      @RequestParam(name = "refundTimeE", required = false) Long refundTimeE,
                                      @RequestParam(name = "pageNum", required = true) Integer pageNum,
                                      @RequestParam(name = "pageSize", required = true) Integer pageSize) {
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("orderNo", orderNo);
            param.put("orderChildNo", orderChildNo);
            param.put("refundOrderNo", refundOrderNo);
            param.put("memPhone", memPhone);
            param.put("goodsType", goodsType);
            param.put("goodsName", goodsName);
            param.put("status", status);
            param.put("createTimeS", createTimeS);
            param.put("createTimeE", createTimeE);
            param.put("refundTimeS", refundTimeS);
            param.put("refundTimeE", refundTimeE);

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

        } catch (Exception e) {
            log.error("OrderRefundController -> getRefundList() error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/excelRefund",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "导出退款")
    public ResponseData excelRefund(@RequestParam(name = "orderNo", required = false) String orderNo,
                                    @RequestParam(name = "orderChildNo", required = false) String orderChildNo,
                                    @RequestParam(name = "refundOrderNo", required = false) String refundOrderNo,
                                    @RequestParam(name = "payType", required = false) Integer payType,
                                    @RequestParam(name = "memPhone", required = false) String memPhone,
                                    @RequestParam(name = "goodsType", required = false) Integer goodsType,
                                    @RequestParam(name = "goodsName", required = false) String goodsName,
                                    @RequestParam(name = "status", required = false) Integer status,
                                    @RequestParam(name = "createTimeS", required = false) Long createTimeS,
                                    @RequestParam(name = "createTimeE", required = false) Long createTimeE,
                                    @RequestParam(name = "refundTimeS", required = false) Long refundTimeS,
                                    @RequestParam(name = "refundTimeE", required = false) Long refundTimeE) {
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("orderNo", orderNo);
            param.put("orderChildNo", orderChildNo);
            param.put("refundOrderNo", refundOrderNo);
            param.put("payType", payType);
            param.put("memPhone", memPhone);
            param.put("goodsType", goodsType);
            param.put("goodsName", goodsName);
            param.put("status", status);
            param.put("createTimeS", createTimeS);
            param.put("createTimeE", createTimeE);
            param.put("refundTimeS", refundTimeS);
            param.put("refundTimeE", refundTimeE);

            List<HighOrderRefund> list = orderRefundService.getRefundOrderList(param);

            List<ExportOrderRefundModel> orderRefundModelList = new ArrayList<>();
            ExportOrderRefundModel orderRefundModel;

            for (HighOrderRefund orderRefund : list) {
                orderRefundModel = new ExportOrderRefundModel();
                orderRefundModel.setOrderNo(orderRefund.getOrderNo());
                OrderPayType orderPayType = OrderPayType.getDataByType(orderRefund.getPayType());
                orderRefundModel.setPayTypeName(orderPayType!=null?orderPayType.getName():"未知");
                orderRefundModel.setChildOrderNo(orderRefund.getOrderChildNo());
                orderRefundModel.setMemPhone(orderRefund.getMemPhone());
                orderRefundModel.setGoodsType(OrderChildGoodsType.getDataByType(orderRefund.getGoodsType()).getName());
                orderRefundModel.setGoodsName(orderRefund.getGoodsName());
                orderRefundModel.setRefundOrderNo(orderRefund.getRefundOrderNo());
                orderRefundModel.setRefundGoodsNum(orderRefund.getRefundGoodsNum());
                orderRefundModel.setReturnTotalPrice(orderRefund.getReturnTotalPrice());
                orderRefundModel.setRefundPrice(orderRefund.getRefundPrice());
                orderRefundModel.setRefundIntegral(orderRefund.getRefundIntegral());
                orderRefundModel.setAccountMerchantNum(orderRefund.getAccountMerchantNum());
                orderRefundModel.setRefundStatus(OrderRefundStatus.getDataByType(orderRefund.getRefundStatus()).getName());
                orderRefundModel.setCreateTime(orderRefund.getCreateTime());
                orderRefundModel.setRefundTime(orderRefund.getRefundTime());
                orderRefundModel.setRefundRemark(orderRefund.getRefundRemark());
                orderRefundModelList.add(orderRefundModel);
            }

            String fileUrl = SysConst.getSysConfig().getFileUrl() + "/temporary/";
            String pathName = System.currentTimeMillis()+".xlsx";
            File file = new File(fileUrl);
            if (!file.exists()) {
                file.mkdirs();
            }
            EasyExcel.write(fileUrl+pathName)
                    .head(ExportOrderRefundModel.class)
                    .sheet("交易退款记录")
                    .doWrite(orderRefundModelList);

            return ResponseMsgUtil.success("/temporary/" + pathName);

        } catch (Exception e) {
            log.error("OrderRefundController -> excelRefund() error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

}
