package com.cweb.controller.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.utils.DateUtil;
import com.hai.common.utils.IDGenerator;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.config.*;
import com.hai.dao.HighCouponCodeOtherMapper;
import com.hai.dao.HighGasOrderPushMapper;
import com.hai.dao.HighPayRecordMapper;
import com.hai.dao.HighUserCouponMapper;
import com.hai.entity.*;
import com.hai.enum_type.MerStoreAmountSourceTypeEnum;
import com.hai.enum_type.MerStoreAmountTypeEnum;
import com.hai.enum_type.MerchantStoreSourceType;
import com.hai.enum_type.OrderPushType;
import com.hai.model.HighMerchantStoreModel;
import com.hai.model.ResponseData;
import com.hai.msg.entity.MsgTopic;
import com.hai.service.*;
import com.hai.service.pay.NotifyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.*;

@Controller
@RequestMapping(value = "/unionPay")
@Api(value = "银联支付")
public class UnionPayController {

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

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private HighOrderService highOrderService;

    @Resource
    private HighOrderPreService highOrderPreService;

    @Resource
    private HighGasOrderPushMapper highGasOrderPushMapper;

    @Resource
    private HighCouponService highCouponService;

    @Resource
    private HighCouponCodeService highCouponCodeService;

    @Resource
    private HighUserService highUserService;

    @Resource
    private HighUserCouponMapper highUserCouponMapper;

    @Resource
    private HighMerchantStoreService highMerchantStoreService;

    @Resource
    private HighProfitSharingRecordService highProfitSharingRecordService;

    @Resource
    private HighCouponCodeOtherMapper highCouponCodeOtherMapper;

    @Resource
    private HighActivityInfoService highActivityInfoService;

    @Resource
    private HighActivityUserLotteryNumService highActivityUserLotteryNumService;

    @Resource
    private NotifyService notifyService;

    @Resource
    private HuiLianTongConfig huiLianTongConfig;

    @Resource
    private HighPayRecordMapper highPayRecordMapper;

    @Resource
    private HighDiscountPackageDiscountActualService discountPackageDiscountActualService;

    @Resource
    private HighDiscountPackageActualService discountPackageActualService;

    @Resource
    private HighDiscountPackageService discountPackageService;

    @Resource
    private HighDiscountPackageRecordService discountPackageRecordService;

    @Resource
    private HighDiscountUserRelService highDiscountUserRelService;

    @Resource
    private OutRechargeOrderService outRechargeOrderService;

    @Resource
    private ApiMemberProductService apiMemberProductService;

    @Resource
    private ShellGroupService shellGroupService;

    @Resource
    private JinZhuJiaYouService jinZhuJiaYouService;

    @RequestMapping(value = "/notify", method = RequestMethod.POST)
    @ApiOperation(value = "银联支付 -> 异步回调")
    public void notify(@RequestBody String params,HttpServletRequest request, HttpServletResponse response) {
        try {

            System.out.println(params);
            log.info(params);

            if (StringUtils.isNotBlank(params)) {
                // 参数解码
                String paramsStr = URLDecoder.decode(params,"utf-8");

                // 记录请求参数
                HighPayRecord payRecord = new HighPayRecord();
                payRecord.setCreateTime(new Date());
                payRecord.setResType(2);
                payRecord.setPayType(3);
                payRecord.setBodyInfo(paramsStr);
                highPayRecordMapper.insert(payRecord);

                // 转换成JSON格式
                JSONObject body = JSONObject.parseObject(paramsStr.substring(0, paramsStr.length() - 1));
                if (StringUtils.isNotBlank(body.getString("tradetrace"))) {
                    // 查询订单信息
                    HighOrder order = highOrderService.getOrderByOrderNo(body.getString("tradetrace"));
                    if (order == null) {
                        throw ErrorHelp.genException(SysCode.System, ErrorCode.NOT_FOUND_ORDER, "");
                    }

                    // 查询用户
                    HighUser highUser = highUserService.findByUserId(order.getMemId());

                    if (order.getOrderStatus() == 1) {
                        order.setPaySerialNo(body.getString("wtorderid")); // 支付流水号
                        //order.setPayRealPrice(body.getBigDecimal("payamt")); // 实付金额
                        order.setPayRealPrice(order.getPayPrice()); // 实付金额
                        order.setPayTime(new Date()); // 支付时间
                        order.setPayModel(2);         // 支付模式：1 金币，2 第三方平台，3 混合
                        order.setPayType(5);          // 支付方式： 1：支付宝  2：微信  3：金币  4:工会卡  5:银联   6:银联分期
                        order.setOrderStatus(2);      // 订单状态：1 待支付  2 已支付  3.已完成  4. 已退款  5.已取消

                        for (HighChildOrder highChildOrder : order.getHighChildOrderList()) {
                            // 商品类型   商品类型   1:卡卷   2:金币充值
                            if (highChildOrder.getGoodsType() == 1) {
                                highChildOrder.setChildOrdeStatus(2);  // 子订单状态：1 待支付  2 已支付  3.已完成  4. 已退款  5.已取消

                                HighCoupon coupon = highCouponService.getCouponById(highChildOrder.getGoodsId());

                                // 是否预约
                                if (coupon.getReserveStatus() == true) {
                                    HighOrderPre orderPre = new HighOrderPre();
                                    orderPre.setCompanyId(coupon.getCompanyId());
                                    orderPre.setMerchantId(coupon.getMerchantId());
                                    orderPre.setMerchantStoreId(highChildOrder.getStoreId());
                                    orderPre.setPreOrderNo(System.currentTimeMillis()+"");
                                    orderPre.setOrderId(order.getId());
                                    orderPre.setOrderNo(order.getOrderNo());
                                    orderPre.setChildOrderId(highChildOrder.getId());
                                    orderPre.setPayRealPrice(order.getPayRealPrice());
                                    orderPre.setGoodsType(1);
                                    orderPre.setGoodsName(coupon.getCouponName());
                                    orderPre.setGoodsId(coupon.getId());
                                    orderPre.setPreUserId(order.getMemId());
                                    orderPre.setPreUserName(order.getMemName());
                                    orderPre.setPreUserPhone(order.getMemPhone());
                                    orderPre.setPreUserRemark(order.getRemarks());
                                    orderPre.setStatus(1);
                                    highOrderPreService.insertOrderPre(orderPre);
                                }

                                // 贵州中石化
                                if (coupon.getCouponSource() == 4) {
                                    Map<String,Object> push = new HashMap<>();
                                    push.put("couTypeCode", coupon.getCouponKey());
                                    push.put("distCouCount", highChildOrder.getSaleCount());
                                    push.put("userPhone", highUser.getPhone());
                                    push.put("thirdUserId", highUser.getUnionId());

                                    // 推送给高速
                                    JSONObject returnParam = HuiLianTongConfig.costRechargeOrder(highChildOrder.getExt2());
                                    if (returnParam != null && returnParam.getString("respCode").equals("0000")) {
                                        // 解密
                                        JSONObject jsonObject = HuiLianTongUnionCardConfig.resolveResponse(returnParam.getString("data"));
                                        JSONArray dataArray = JSONObject.parseObject(jsonObject.getString("data"), JSONArray.class);
                                        for (Object data : dataArray) {
                                            JSONObject dataObject = (JSONObject) data;
                                            HighCouponCodeOther couponCodeOther = new HighCouponCodeOther();
                                            couponCodeOther.setType(1);
                                            couponCodeOther.setOrderId(order.getId());
                                            couponCodeOther.setChildOrderId(highChildOrder.getId());
                                            couponCodeOther.setCouTypeCode(dataObject.getString("couTypeCode"));
                                            couponCodeOther.setCouNo(dataObject.getString("couNo"));
                                            couponCodeOther.setActiveTime(dataObject.getDate("activeTime"));
                                            couponCodeOther.setValidStartDate(dataObject.getDate("validStartDate"));
                                            couponCodeOther.setValidEndDate(dataObject.getDate("validEndDate"));
                                            couponCodeOther.setStatus(20);
                                            couponCodeOther.setCreateTime(new Date());
                                            highCouponCodeOtherMapper.insert(couponCodeOther);

                                            // 卡卷关联用户
                                            HighUserCoupon highUserCoupon = new HighUserCoupon();
                                            highUserCoupon.setMerchantId(coupon.getMerchantId());
                                            highUserCoupon.setCouponId(coupon.getId());
                                            highUserCoupon.setUserId(order.getMemId());
                                            highUserCoupon.setCreateTime(new Date());
                                            highUserCoupon.setQrCodeImg(dataObject.getString("couNo"));
                                            highUserCoupon.setUseEndTime(dataObject.getDate("validEndDate"));
                                            highUserCoupon.setStatus(1);  // 状态  0:已过期  1：未使用  2：已使用
                                            highUserCouponMapper.insert(highUserCoupon);
                                        }
                                    }

                                    // 推送记录
                                    HighGasOrderPush highGasOrderPush = new HighGasOrderPush();
                                    highGasOrderPush.setType(OrderPushType.type6.getType());
                                    highGasOrderPush.setOrderNo(order.getOrderNo());
                                    highGasOrderPush.setCreateTime(new Date());
                                    highGasOrderPush.setCode(returnParam.getString("result"));
                                    highGasOrderPush.setRequestContent(JSONObject.toJSONString(push));
                                    highGasOrderPush.setReturnContent(returnParam.toJSONString());
                                    highGasOrderPushMapper.insert(highGasOrderPush);

                                } else {
                                    HighCouponCode code = highCouponCodeService.getCouponCodeByOrderId(highChildOrder.getId());
                                    code.setStatus(2);  // 状态：1.待销售 2.未使用 3.已使用  99.预支付
                                    code.setReceiveTime(new Date());
                                    highCouponCodeService.updateCouponCode(code);
                                    // 卡卷关联用户
                                    HighUserCoupon highUserCoupon = new HighUserCoupon();
                                    highUserCoupon.setMerchantId(code.getMerchantId());
                                    highUserCoupon.setCouponId(code.getCouponId());
                                    highUserCoupon.setUserId(order.getMemId());
                                    highUserCoupon.setCouponCodeId(code.getId());
                                    highUserCoupon.setCreateTime(new Date());
                                    highUserCoupon.setQrCodeImg(code.getExt1());

                                    // 计算使用有效期
                                    Calendar userEndTime = Calendar.getInstance();
                                    userEndTime.setTime(new Date());
                                    userEndTime.set(Calendar.HOUR_OF_DAY, 23);
                                    userEndTime.set(Calendar.MINUTE, 59);
                                    userEndTime.set(Calendar.SECOND, 59);
                                    userEndTime.add(Calendar.DATE, coupon.getRecycleDay());
                                    if (userEndTime.getTime().compareTo(code.getUseEndTime()) == 1) {
                                        highUserCoupon.setUseEndTime(code.getUseEndTime());
                                    } else {
                                        highUserCoupon.setUseEndTime(userEndTime.getTime());
                                    }
                                    highUserCoupon.setStatus(1);  // 状态  0:已过期  1：未使用  2：已使用
                                    highUserCouponMapper.insert(highUserCoupon);
                                }

                                // 查询卡券是否有活动
                                Map<String, Object> activity = highActivityInfoService.getNewActivityByCouponId(coupon.getId());
                                if (activity != null && MapUtils.getLong(activity, "id") != null) {
                                    highActivityUserLotteryNumService.addLotteryNum(MapUtils.getLong(activity, "id"),order.getMemId(), 1);
                                }
                            }

                            if (highChildOrder.getGoodsType() == 2) {
                                highChildOrder.setChildOrdeStatus(3);  // 子订单状态：1 待支付  2 已支付  3.已完成  4. 已退款  5.已取消
                                // 金币 1：100
                                Integer goldNum = new BigDecimal(highChildOrder.getTotalPrice().toString()).multiply(new BigDecimal("100")).intValue();
                                String remark = "订单" + order.getOrderNo() + "积分充值积分：" +  goldNum;
                                highUserService.goldHandle(highChildOrder.getGoodsId(), goldNum, 1, 1, highChildOrder.getId() , remark);
                            }

                            if (highChildOrder.getGoodsType() == 3) {
                                highChildOrder.setChildOrdeStatus(3);
                                order.setOrderStatus(3);
                                HighMerchantStoreModel store = highMerchantStoreService.getMerchantStoreById(highChildOrder.getGoodsId());

                                // 来源类型  1：平台自建   2：团油
                                if (store.getSourceType().equals(1)) {

                                    // 预存类型  0：非预存  1：预存门店
                                    if (store.getPrestoreType() != null && store.getPrestoreType().equals(1)) {
                                        Map<String, Object> pushParam = new HashMap<>();
                                        pushParam.put("businessType", MerStoreAmountTypeEnum.type2.getType());
                                        pushParam.put("storeId", highChildOrder.getGoodsId());
                                        pushParam.put("price", order.getTotalPrice());
                                        pushParam.put("sourceType", MerStoreAmountSourceTypeEnum.type2.getType());
                                        pushParam.put("sourceId", order.getId());
                                        pushParam.put("sourceContent", "订单号：" + order.getOrderNo() + ",加油金额：￥" + order.getTotalPrice());
                                        pushParam.put("opUserId", order.getMemId());
                                        pushParam.put("opUserName", order.getMemName());
                                        // 扣预存款
                                        this.redisTemplate.boundListOps(MsgTopic.MerStoreAccount.getName()).leftPush(pushParam);
                                    }

                                } else if (store.getSourceType().equals(2)) {
                                    // 推送团油订单
                                    Map<String,Object> paramMap = new HashMap<>();
                                    paramMap.put("gasId", store.getStoreKey());
                                    paramMap.put("oilNo", highChildOrder.getGasOilNo());
                                    paramMap.put("gunNo", highChildOrder.getGasGunNo());
                                    BigDecimal priceGun = highChildOrder.getGasPriceGun();
                                    BigDecimal priceVip = highChildOrder.getGasPriceVip();
                                    paramMap.put("priceGun", priceGun);  // 枪单价
                                    paramMap.put("priceVip", priceVip);  // 优惠价
                                    paramMap.put("driverPhone", order.getMemPhone());
                                    paramMap.put("thirdSerialNo", order.getOrderNo());
                                    paramMap.put("refuelingAmount", highChildOrder.getTotalPrice());

                                    // 油品类型 1:汽油:2:柴油;3:天然气
                                    if (highChildOrder.getGasOilType() == 1) {
                                        paramMap.put("accountNo", CommonSysConst.getSysConfig().getTuanYouGasolineAccount());
                                    } else if (highChildOrder.getGasOilType() == 2) {
                                        paramMap.put("accountNo", CommonSysConst.getSysConfig().getTuanYouDieselAccount());
                                    }
                                    JSONObject orderPushObject = TuanYouConfig.refuelingOrderPush(paramMap);
                                    // 推送团油订单记录
                                    HighGasOrderPush highGasOrderPush = new HighGasOrderPush();
                                    highGasOrderPush.setType(OrderPushType.type1.getType());
                                    highGasOrderPush.setOrderNo(order.getOrderNo());
                                    highGasOrderPush.setCreateTime(new Date());
                                    highGasOrderPush.setCode(orderPushObject.getString("code"));
                                    highGasOrderPush.setRequestContent(JSONObject.toJSONString(paramMap));
                                    highGasOrderPush.setReturnContent(orderPushObject.toJSONString());
                                    highGasOrderPushMapper.insert(highGasOrderPush);

                                    if (orderPushObject != null && orderPushObject.getString("code").equals("200")) {
                                        highChildOrder.setGasOrderNo(orderPushObject.getJSONObject("result").getString("orderNo"));
                                    }
                                } else if (store.getSourceType().equals(MerchantStoreSourceType.type3.getNumber())) {

                                    // 推送加好油
                                    shellGroupService.gasSyncPayment(order.getOrderNo(),
                                            store.getStoreKey(),
                                            order.getPayTime(),
                                            highChildOrder.getTotalPrice(),
                                            highChildOrder.getGasOilNo(),
                                            highChildOrder.getGasGunNo(),
                                            order.getPayablePrice(),
                                            order.getDeductionPrice()
                                    );

                                } else if (store.getSourceType().equals(MerchantStoreSourceType.type4.getNumber())) {
                                    // 推送金猪加油
                                    jinZhuJiaYouService.payOrder(order.getOrderNo(), highChildOrder.getGasPriceChannelPay());
                                }
                            }
                            if (highChildOrder.getGoodsType() == 4 || highChildOrder.getGoodsType() == 9) {
                                highChildOrder.setChildOrdeStatus(2);
                            }
                        }

                        HighGasOrderPush orderPush = new HighGasOrderPush();
                        JSONObject returnObject = new JSONObject();

                        if (order.getHighChildOrderList().get(0).getGoodsType() == 4) {
                            returnObject = QianZhuConfig.payKfcOrder(order.getOrderNo());
                        } else if (order.getHighChildOrderList().get(0).getGoodsType() == 9) {
                            returnObject = QianZhuConfig.starbucksOrdersPay(order.getOrderNo());
                        } else if (order.getHighChildOrderList().get(0).getGoodsType() == 10){
                            orderPush.setType(OrderPushType.type9.getType());
                            ApiMemberProduct memberProduct = apiMemberProductService.findById(order.getHighChildOrderList().get(0).getGoodsId());
                            returnObject = QianZhuConfig.insertV2(memberProduct.getProductId() , order.getOrderNo() , order.getRemarks());
                        }

                        highOrderService.updateOrder(order);

                        orderPush.setOrderNo(order.getOrderNo());
                        orderPush.setCreateTime(new Date());
                        orderPush.setRequestContent(order.getOrderNo());
                        orderPush.setReturnContent(returnObject.toJSONString());
                        highGasOrderPushMapper.insert(orderPush);


                        if (order.getHighChildOrderList().get(0).getGoodsType().equals(3)) {
                            new Thread(() -> {
                                highOrderService.printGasOrder(order.getHighChildOrderList().get(0).getGoodsId(), order, false);
                            }).start();
                        }
                    }
                }
            }


            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            JSONObject result = new JSONObject();
            result.put("resultcode", "00");
            out.write(result.toJSONString().getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
             log.error("UnionPayController --> notify() error!", e);
        }
    }


    @RequestMapping(value = "/notifyTel", method = RequestMethod.POST)
    @ApiOperation(value = "银联支付 -> 异步回调")
    public void notifyTel(@RequestBody String params,HttpServletRequest request, HttpServletResponse response) {
        try {

            System.out.println(params);
            log.info(params);

            if (StringUtils.isNotBlank(params)) {
                // 参数解码
                String paramsStr = URLDecoder.decode(params,"utf-8");

                // 记录请求参数
                HighPayRecord payRecord = new HighPayRecord();
                payRecord.setCreateTime(new Date());
                payRecord.setResType(2);
                payRecord.setPayType(3);
                payRecord.setBodyInfo(paramsStr);
                highPayRecordMapper.insert(payRecord);

                // 转换成JSON格式
                JSONObject body = JSONObject.parseObject(paramsStr.substring(0, paramsStr.length() - 1));
                if (StringUtils.isNotBlank(body.getString("tradetrace"))) {
                    OutRechargeOrder order = outRechargeOrderService.findByOrderNo(body.getString("tradetrace"));
                    if (order == null) {
                        throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单信息");
                    }

                    order.setPaySerialNo(body.getString("wtorderid")); // 支付流水号
                    order.setPayRealPrice(order.getPayRealPrice()); // 实付金额

                    order.setPayStatus(102);
                    order.setRechargeStatus(204);
                    order.setPayType(4);
                    order.setPayTime(new Date()); // 支付时间
                    outRechargeOrderService.updateOrder(order);
                    outRechargeOrderService.pollRequest(order);
                }
            }

            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            JSONObject result = new JSONObject();
            result.put("resultcode", "00");
            out.write(result.toJSONString().getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            log.error("UnionPayController --> notify() error!", e);
        }
    }

    @RequestMapping(value = "/refreshStagingOrder", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "银联分期支付 -> 刷新分期订单")
    public ResponseData refreshStagingOrder(@RequestBody JSONObject body, HttpServletRequest request, HttpServletResponse response) {
        try {

            if (body == null || StringUtils.isBlank(body.getString("orderNo"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            // 查询订单信息
            HighOrder order = highOrderService.getOrderByOrderNo(body.getString("orderNo"));
            if (order == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单信息");
            }
            // 订单状态：1 待支付  2 已支付  3.已完成  4. 已退款  5.已取消   6.退款中   7.拒绝退款
            if (order.getOrderStatus().equals(1)) {
                String orgTrace = CommonSysConst.getSysConfig().getUnionStagingPayOrgId().substring(0,4)
                        +CommonSysConst.getSysConfig().getUnionStagingPayOrgId().substring(CommonSysConst.getSysConfig().getUnionStagingPayOrgId().length() - 4,CommonSysConst.getSysConfig().getUnionStagingPayOrgId().length())
                        + DateUtil.format(new Date(), DateUtil.YMDHMS)
                        + IDGenerator.nextId(6);

                JSONObject responseObject = UnionStagingPayConfig.queryStaging(orgTrace, order.getPaySerialNo(), "", order.getCreateTime(), request);
                if (responseObject.getString("sysRetCode").equals("000000")) {

                }

                return ResponseMsgUtil.success(responseObject);
            }
            return ResponseMsgUtil.success(order);

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

}
