package com.web.controller.business;

import com.alibaba.excel.EasyExcel;
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.RedisUtil;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.entity.HighOrder;
import com.hai.entity.OutRechargeChildOrder;
import com.hai.entity.OutRechargeOrder;
import com.hai.enum_type.OrderStatusEnum;
import com.hai.enum_type.UserObjectTypeEnum;
import com.hai.model.ResponseData;
import com.hai.model.UserInfoModel;
import com.hai.order.model.ExportOrderMobileModel;
import com.hai.order.model.OrderThirdPartyModel;
import com.hai.order.service.OrderService;
import com.hai.order.type.OrderPayType;
import com.hai.order.type.OrderStatus;
import com.hai.order.type.RechargePlatformType;
import com.hai.service.HighOrderService;
import com.hai.service.OutRechargeChildOrderService;
import com.hai.service.OutRechargeOrderService;
import com.hai.service.impl.OutRechargeOrderServiceImpl;
import com.web.config.SysConst;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping(value = "mobileRecharge")
@Api(value = "话费充值业务")
public class OrderMobileRechargeController {

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

    @Resource
    private UserCenter userCenter;

    @Resource
    private OutRechargeOrderService outRechargeOrderService;

    @Resource
    private OrderService orderService;

    @Resource
    private HighOrderService highOrderService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private OutRechargeChildOrderService outRechargeChildOrderService;

    @RequestMapping(value = "/getOrderList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询话费订单列表")
    public ResponseData getOrderList(@RequestParam(name = "orderNo", required = false) String orderNo,
                                     @RequestParam(name = "memPhone", required = false) String memPhone,
                                     @RequestParam(name = "memCardNo", required = false) String memCardNo,
                                     @RequestParam(name = "title", required = false) String title,
                                     @RequestParam(name = "exceptionStatus", required = false) Boolean exceptionStatus,
                                     @RequestParam(name = "payType", required = false) Integer payType,
                                     @RequestParam(name = "orderStatus", required = false) Integer orderStatus,
                                     @RequestParam(name = "companyId", required = false) Long companyId,
                                     @RequestParam(name = "createTimeS", required = false) Long createTimeS,
                                     @RequestParam(name = "createTimeE", required = false) Long createTimeE,
                                     @RequestParam(name = "payTimeS", required = false) Long payTimeS,
                                     @RequestParam(name = "payTimeE", required = false) Long payTimeE,
                                     @RequestParam(name = "finishTimeS", required = false) Long finishTimeS,
                                     @RequestParam(name = "finishTimeE", required = false) Long finishTimeE,
                                     @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,
                                     HttpServletRequest request) {
        try {

            UserInfoModel userInfoModel = userCenter.getSessionModel(UserInfoModel.class);
            if (userInfoModel == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMPETENCE_INSUFFICIENT, "");
            }
            Map<String,Object> map = new HashMap<>();
            if (userInfoModel.getSecUser().getObjectType().equals(UserObjectTypeEnum.type0.getType())) {
                map.put("companyId" , companyId);
            } else if (userInfoModel.getSecUser().getObjectType().equals(UserObjectTypeEnum.type1.getType())) {
                map.put("companyId", userInfoModel.getBsCompany().getId());
            } else {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMPETENCE_INSUFFICIENT, "");
            }

            map.put("exceptionStatus", exceptionStatus);
            map.put("createTimeS", createTimeS);
            map.put("createTimeE", createTimeE);
            map.put("payTimeS", payTimeS);
            map.put("payTimeE", payTimeE);
            map.put("refundTimeS" , refundTimeS);
            map.put("refundTimeE" , refundTimeE);
            map.put("finishTimeS", finishTimeS);
            map.put("finishTimeE", finishTimeE);
            map.put("title", title);
            map.put("orderNo", orderNo);
            map.put("memPhone", memPhone);
            map.put("memCardNo", memCardNo);
            map.put("productType", 9);
            map.put("orderStatus", orderStatus);
            map.put("payType", payType);

            PageHelper.startPage(pageNum,pageSize);
            return ResponseMsgUtil.success(new PageInfo<>(orderService.getOrderList(map)));

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

    @RequestMapping(value = "/exportMobilePartyOrderList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "导出话费订单列表")
    public ResponseData exportMobilePartyOrderList(@RequestParam(name = "orderNo", required = false) String orderNo,
                                                  @RequestParam(name = "memPhone", required = false) String memPhone,
                                                   @RequestParam(name = "serialNumber", required = false) String serialNumber,
                                                  @RequestParam(name = "memCardNo", required = false) String memCardNo,
                                                  @RequestParam(name = "payType", required = false) Integer payType,
                                                  @RequestParam(name = "orderStatus", required = false) Integer orderStatus,
                                                  @RequestParam(name = "companyId", required = false) Long companyId,
                                                  @RequestParam(name = "exceptionStatus", required = false) Boolean exceptionStatus,
                                                  @RequestParam(name = "createTimeS", required = false) Long createTimeS,
                                                  @RequestParam(name = "title", required = false) String title,
                                                  @RequestParam(name = "createTimeE", required = false) Long createTimeE,
                                                  @RequestParam(name = "payTimeS", required = false) Long payTimeS,
                                                  @RequestParam(name = "payTimeE", required = false) Long payTimeE,
                                                  @RequestParam(name = "productType", required = false) Integer productType,
                                                   @RequestParam(name = "refundTimeS", required = false) Long refundTimeS,
                                                   @RequestParam(name = "refundTimeE", required = false) Long refundTimeE,
                                                  @RequestParam(name = "finishTimeS", required = false) Long finishTimeS,

                                                  @RequestParam(name = "finishTimeE", required = false) Long finishTimeE) {
        try {

            UserInfoModel userInfoModel = userCenter.getSessionModel(UserInfoModel.class);
            if (userInfoModel == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMPETENCE_INSUFFICIENT, "");
            }
            Map<String,Object> map = new HashMap<>();
            if (userInfoModel.getSecUser().getObjectType().equals(UserObjectTypeEnum.type0.getType())) {
                map.put("companyId" , companyId);
            } else if (userInfoModel.getSecUser().getObjectType().equals(UserObjectTypeEnum.type1.getType())) {
                map.put("companyId", userInfoModel.getBsCompany().getId());
            } else {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMPETENCE_INSUFFICIENT, "");
            }
            map.put("createTimeS", createTimeS);
            map.put("createTimeE", createTimeE);
            map.put("exceptionStatus", exceptionStatus);
            map.put("payTimeS", payTimeS);
            map.put("payTimeE", payTimeE);
            map.put("finishTimeS", finishTimeS);
            map.put("finishTimeE", finishTimeE);
            map.put("refundTimeS" , refundTimeS);
            map.put("refundTimeE" , refundTimeE);
            map.put("title", title);
            map.put("orderNo", orderNo);
            map.put("memPhone", memPhone);
            map.put("memCardNo", memCardNo);
            map.put("productType", 9);
            map.put("orderStatus", orderStatus);
            map.put("payType", payType);

            // 查询数据
            List<HighOrder> order = orderService.getOrderList(map);

            List<ExportOrderMobileModel> list = new ArrayList<>();

            // 配置初始化处理条数
            int i = 0;
            int percent;

            ExportOrderMobileModel model;
            for (HighOrder highOrder : order) {

                i++;

                // 生成百分比
                percent = i*100/order.size();

                redisUtil.set(serialNumber , percent , 3600);

                model = new ExportOrderMobileModel();

                OutRechargeOrder rechargeOrder = outRechargeOrderService.findByOrderNoNotChild(highOrder.getOrderNo());

                if (rechargeOrder != null) {

                    OutRechargeChildOrder childOrder = outRechargeOrderService.mobileChildOrderHandle(highOrder,rechargeOrder);

                    model.setRechargeOrderNo(rechargeOrder.getOrderNo());

                    if (childOrder != null) {
                        model.setChildOrderNo(childOrder.getOrderNo());
                        if (childOrder.getRechargePlatform() != null) {
                            model.setRechargePlatform(RechargePlatformType.getDataByType(childOrder.getRechargePlatform()).getName());
                        }
                        model.setRemark(childOrder.getExt1());
                    }

                }
                model.setFinishTime(highOrder.getFinishTime());
                model.setOrderStatus(OrderStatus.getDataByType(highOrder.getOrderStatus()).getName());
                model.setMemPhone(highOrder.getMemPhone());
                model.setCreateTime(highOrder.getCreateTime());
                model.setTitle(highOrder.getTitle());
                model.setPayablePrice(highOrder.getPayablePrice());
                model.setRefundTime(highOrder.getRefundTime());
                model.setPayPrice(highOrder.getPayPrice());
                model.setOrderNo(highOrder.getOrderNo());
                model.setMemCardNo(highOrder.getMemCardNo());
                if (highOrder.getPayType() != null) {
                    model.setPayType(OrderPayType.getDataByType(highOrder.getPayType()).getName());
                }
                list.add(model);
            }

            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(ExportOrderMobileModel.class)
                    .sheet("话费交易订单")
                    .doWrite(list);

            redisUtil.set(serialNumber + "download" , pathName , 600);
            return ResponseMsgUtil.success(pathName);

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

    @RequestMapping(value="/getMobileOrderDetail",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询话费订单详情")
    public ResponseData getMobileOrderDetail(@RequestParam(name = "orderNo", required = true) String orderNo) {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("tradeOrder", orderService.getOrderDetail(orderNo));
            map.put("mobileOrder", outRechargeOrderService.findByOrderNo(orderNo));
            return ResponseMsgUtil.success(map);

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

    @RequestMapping(value="/refundOrder",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "订单退款")
    public ResponseData refundOrder(@RequestParam(name = "orderNo", required = true) String orderNo) {

        OutRechargeOrder outRechargeOrder = outRechargeOrderService.findByOrderNo(orderNo);

        String key = "recharge_" + outRechargeOrder.getId();
        try {

            // 分布式锁占坑
            Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, outRechargeOrder.getOrderNo());

            if(Boolean.TRUE.equals(lock)) {
                // 加锁成功，处理业务
                // 判断订单是否可以继续充值 1：满足继续充值条件 2：订单满足退款条件 3：订单不可以退款不可以继续充值 4:订单存在多个充值订单 5:订单充值完成 6：充值订单号未查询到任何充值记录
                int orderStatus = outRechargeOrderService.orderWhetherRecharge(outRechargeOrder);
                if (orderStatus == 2) {
                    outRechargeOrderService.refundOrder(outRechargeOrder.getId());
                }
                if (orderStatus == 6) {
                    outRechargeOrderService.refundOrder(outRechargeOrder.getId());
                }
            } else {
                // 加锁失败，重试
                Thread.sleep(100);
                refundOrder(orderNo);
            }



            HighOrder order  = highOrderService.getOrderByOrderNo(orderNo);
            order.setExceptionStatus(false);
            highOrderService.updateOrder(order);

            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            log.error("OrderExtController -> getGasOrderDetail() error!",e);
            return ResponseMsgUtil.exception(e);
        } finally {
            // 删除key，释放锁
            redisTemplate.delete(key);
        }
    }

    @RequestMapping(value="/orderNormal",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "订单修改正常")
    public ResponseData orderNormal(@RequestParam(name = "orderNo", required = true) String orderNo) {


        try {

            OutRechargeOrder rechargeOrder = outRechargeOrderService.findByOrderNo(orderNo);

            List<OutRechargeChildOrder> rechargeChildOrderList = outRechargeChildOrderService.getListRechargeChildOrderByOrderId(rechargeOrder.getId());

            for (OutRechargeChildOrder rechargeChildOrder : rechargeChildOrderList) {
                if (rechargeChildOrder.getStatus() == 104) {
                    rechargeChildOrder.setStatus(102);
                }
                outRechargeChildOrderService.updateOrder(rechargeChildOrder);
            }

            HighOrder order  = highOrderService.getOrderByOrderNo(orderNo);
            order.setExceptionStatus(false);
            highOrderService.updateOrder(order);

            return ResponseMsgUtil.success("操作成功");

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


}
