package com.cweb.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.PayModeModel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hfkj.channel.lakala.LaKaLaTradeService;
import com.hfkj.channel.tianque.service.TianQueTradeService;
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.HttpsUtils;
import com.hfkj.common.utils.ResponseMsgUtil;
import com.hfkj.config.CommonSysConst;
import com.hfkj.config.hsg.UserDiscountService;
import com.hfkj.entity.*;
import com.hfkj.model.ResponseData;
import com.hfkj.model.UserDiscount;
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.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

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

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

    @Resource
    private BsTradeOrderService tradeOrderService;

    @Resource
    private BsTradeOrderRefundService tradeOrderRefundService;

    @Resource
    private BsStoreService storeService;

    @Resource
    private BsStoreDiscountActivityService storeDiscountActivityService;

    @Resource
    private BsMerService merService;

    @Resource
    private UserCenter userCenter;

    @Resource
    private BsDeviceService deviceService;

    @Resource
    private BsPayQrCodeService payQrCodeService;

    @Resource
    private BsMerPlatformNoService platformNoService;

    @Resource
    private BsMerPlatformTermService platformTermService;
    @Resource
    private LaKaLaTradeService laKaLaTradeService;
    @Resource
    private TianQueTradeService tianQueTradeService;

    @RequestMapping(value="/calculation",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "计算支付金额")
    public ResponseData calculation(@RequestParam(name = "transactionPrice", required = true) BigDecimal transactionPrice,
                                    @RequestParam(name = "storeDiscountType", required = false) Integer storeDiscountType,
                                    @RequestParam(name = "storeDiscountPrice", required = false) BigDecimal storeDiscountPrice,
                                    @RequestParam(name = "userDiscountType", required = false) Integer userDiscountType,
                                    @RequestParam(name = "userDiscountPrice", required = false) BigDecimal userDiscountPrice) {
        try {
            if (transactionPrice.compareTo(new BigDecimal("0")) <= 0) {
                return ResponseMsgUtil.success(0);
            }

            BigDecimal payable = transactionPrice;

            if (storeDiscountType != null && storeDiscountPrice != null) {
                if (StoreDiscountActivityTypeEnum.getDataByNumber(storeDiscountType) == null) {
                    log.error("calculation error!","未知的优惠类型");
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的优惠类型");
                }
                if (storeDiscountType.equals(StoreDiscountActivityTypeEnum.type3.getNumber())) {
                    // 优惠比例 / 100 = 最终优惠比例
                    BigDecimal priceRate = storeDiscountPrice.divide(new BigDecimal("100").setScale(2, BigDecimal.ROUND_DOWN));
                    payable = payable.multiply(priceRate).setScale(2, BigDecimal.ROUND_HALF_UP);
                } else {
                    payable = payable.subtract(storeDiscountPrice);
                }
            }

            if (userDiscountType != null && userDiscountPrice != null) {
                if (UserDiscountTypeEnum.getDataByNumber(userDiscountType) == null) {
                    log.error("calculation error!","未知的优惠类型");
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的优惠类型");
                }
                if (userDiscountType.equals(UserDiscountTypeEnum.type3.getNumber())) {
                    // 优惠比例 / 100 = 最终优惠比例
                    BigDecimal priceRate = userDiscountPrice.setScale(2, BigDecimal.ROUND_DOWN);
                    payable = payable.multiply(priceRate).setScale(2, BigDecimal.ROUND_HALF_UP);
                } else {
                    payable = payable.subtract(userDiscountPrice);
                }
            }

            if (payable.compareTo(new BigDecimal("0")) <= 0) {
                return ResponseMsgUtil.success(0);
            }

            return ResponseMsgUtil.success(payable);

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

    @RequestMapping(value="/createMicroOrder",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "创建交易【被扫】订单")
    public ResponseData createMicroOrder(@RequestBody JSONObject body, HttpServletRequest request) {
        try {

            if (body == null
                    || body.getString("deviceSN") == null
                    || body.getBigDecimal("totalAmount") == null
            ) {
                log.error("configStore error!", "参数错误");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }

            if (body.getBigDecimal("totalAmount").compareTo(new BigDecimal("0.01")) == -1) {
                log.error("configStore error!", "参数错误");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "支付金额不能小于0.01");
            }

            // 查询设备编号
            BsDevice device = deviceService.getDetailByNo(body.getString("deviceNo"));
            if (device == null) {
                log.error("configStore error!", "未知的设备编号");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的设备编号");
            }
            if (device.getStoreId() == null) {
                log.error("configStore error!", "未知的设备编号");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备未绑定门店");
            }
            // 查询门店
            BsStore store = storeService.getStoreById(device.getStoreId());
            if (store == null) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的门店");
            }
            if (!store.getStatus().equals(StoreStatusEnum.status2.getNumber())) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "创建交易失败！门店状态异常");
            }
            // 商户
            BsMer mer = merService.getMer(store.getMerId());
            if (mer == null) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
            }
            if (!mer.getMerStatus().equals(MerStatusEnum.status1.getNumber())) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "创建交易失败！商户状态异常");
            }
            Map<String, Object> param = new HashMap<>();
            param.put("deviceSN", body.getString("deviceSN"));
            param.put("deviceId", device.getId());

            // 创建交易订单
            return ResponseMsgUtil.success(tradeOrderService.createOrder(store.getId(), body.getBigDecimal("totalAmount"),null,null, null, param, request));

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

    @RequestMapping(value="/createJSAPIOrder",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "创建交易【JSAPI】订单")
    public ResponseData createJSAPIOrder(@RequestBody JSONObject body, HttpServletRequest request) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("qrCodeSN"))
                    || StringUtils.isBlank(body.getString("payMode"))
                    || StringUtils.isBlank(body.getString("payUserId"))
                    || body.getBigDecimal("totalAmount") == null
            ) {
                log.error("configStore error!", "参数错误");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }

            TradeOrderPayModeEnum payMode = TradeOrderPayModeEnum.getNameByCode(body.getString("payMode"));
            if (payMode == null) {
                log.error("configStore error!", "未知支付方式");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知支付方式");
            }
            if (payMode.getCode().equals(TradeOrderPayModeEnum.UQRCODEPAY.getCode()) &&
                body.getBigDecimal("totalAmount").compareTo(new BigDecimal("1000")) == 1) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "云闪付单笔交易限额1000元");
            }

            if (body.getBigDecimal("totalAmount").compareTo(new BigDecimal("0.01")) == -1) {
                log.error("configStore error!", "参数错误");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "支付金额不能小于0.01");
            }

            // 查询二维码
            BsPayQrCode payQrCode = payQrCodeService.getDetailBySN(body.getString("qrCodeSN"));
            if (payQrCode == null) {
                log.error("configStore error!", "未知的二维码序列号");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的二维码序列号");
            }
            if (!payQrCode.getStatus().equals(PayQrCodeStatusEnum.status1.getNumber())) {
                log.error("configStore error!", "二维码状态异常");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "创建交易失败！二维码状态异常");
            }
            if (payQrCode.getStoreId() == null) {
                log.error("configStore error!", "二维码未绑定门店");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "创建交易失败！二维码未绑定门店");
            }
            // 查询门店
            BsStore store = storeService.getStoreById(payQrCode.getStoreId());
            if (store == null) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的门店");
            }
            if (!store.getStatus().equals(StoreStatusEnum.status2.getNumber())) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "创建交易失败！门店状态异常");
            }
            // 商户
            BsMer mer = merService.getMer(store.getMerId());
            if (mer == null) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
            }
            if (!mer.getMerStatus().equals(MerStatusEnum.status1.getNumber())) {
                log.error("configStore error!", "");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "创建交易失败！商户状态异常");
            }

            // 优惠活动
            BsStoreDiscountActivity storeDiscountActivity = null;
            if (body.getLong("storeDiscountId") != null) {
                storeDiscountActivity = storeDiscountActivityService.getDetailById(body.getLong("storeDiscountId"));
                if (storeDiscountActivity != null) {
                    if (!storeDiscountActivity.getPartakeWay().equals(StoreDiscountActivityPartakeWayEnum.type1.getNumber())
                        && StringUtils.isBlank(body.getString("userPhone"))) {
                        throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, storeDiscountActivity.getName() + ",需要登录才能参加");
                    }
                }
            }

            // 用户优惠券
            UserDiscount userDiscount = null;
            if (body.getLong("userDiscountId") != null) {
                String token = request.getHeader("Authorization");
                if (token == null) {
                    log.error("configStore error!", "");
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "用户未登录！无法使用优惠券");
                }
                userDiscount = UserDiscountService.getUserDiscountDetail(body.getLong("userDiscountId"), token);
            }

            Map<String, Object> param = new HashMap<>();
            param.put("qrCodeSN", body.getString("qrCodeSN"));
            param.put("qrCodeId", payQrCode.getId());
            param.put("payMode", body.getString("payMode"));
            param.put("payUserId", body.getString("payUserId"));
            param.put("transType", "JSAPI");

            // 创建交易订单
            return ResponseMsgUtil.success(tradeOrderService.createOrder(
                    store.getId(),
                    body.getBigDecimal("totalAmount"),
                    storeDiscountActivity,
                    body.getString("userPhone"),
                    userDiscount,
                    param,
                    request));

        } 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="/getTradeOrderList",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询交易订单列表")
    public ResponseData getTradeOrderList(@RequestParam(value = "salesmanId" , required = false) Long salesmanId,
                                          @RequestParam(value = "merId" , required = false) Long merId,
                                          @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 = "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("agentId", agentId);
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("storeId", storeId);
                param.put("storeName", storeName);
            }
            if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type2.getNumber())) {
                param.put("agentId", userModel.getAgent().getId());
                param.put("salesmanId", salesmanId);
                param.put("merId", merId);
                param.put("storeId", storeId);
                param.put("storeName", storeName);
            }
            if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type3.getNumber())) {
                param.put("salesmanId", userModel.getSalesman().getId());
                param.put("merId", merId);
                param.put("storeId", storeId);
                param.put("storeName", storeName);
            }
            if (userModel.getSecUser().getObjectType().equals(SecUserTypeEnum.type4.getNumber())) {
                param.put("merId", userModel.getMer().getId());
                param.put("storeId", storeId);
                param.put("storeName", storeName);
            }
            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);

            Map<String, Object> map = new HashMap<>();

            Map<String, Object> tradeOrderPrice = tradeOrderService.countTradeOrderPrice(param);
            map.put("totalPrice", tradeOrderPrice.get("tradePrice"));
            map.put("totalNum", tradeOrderPrice.get("count"));

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

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

    @RequestMapping(value="/getUnionUserId",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "获取拉卡拉银联用户id")
    public ResponseData getUnionUserId(@RequestBody JSONObject body) {
        try {
            System.out.println(body);
            if (body == null
                    || StringUtils.isBlank(body.getString("serialNumber"))
                    || StringUtils.isBlank(body.getString("userAuthCode"))
                    || StringUtils.isBlank(body.getString("appUpIdentifier"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            // 查询二维码
            BsPayQrCode qrCode = payQrCodeService.getDetailBySN(body.getString("serialNumber"));
            if (qrCode == null) {
                log.error("BsPayQrCodeController error!","未找到支付码信息");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到支付码信息");
            }
            if (qrCode.getStoreId() == null) {
                log.error("BsPayQrCodeController error!","支付码未绑定门店");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "支付码未绑定门店");
            }
            if (!qrCode.getStatus().equals(PayQrCodeStatusEnum.status1.getNumber())) {
                log.error("BsPayQrCodeController error!","支付码已被停用");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "支付码已被停用");
            }
            BsMerPlatformNo platform = platformNoService.getCurrentPlatform(qrCode.getMerId());
            if (platform == null) {
                log.error("BsPayQrCodeController error!","商户无法支付，未配置支付平台");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户无法支付，未配置支付平台");
            }
            if (platform.getPlatformType().equals(PlatformTypeEnum.type1.getNumber())) {
                // 查询商户号
                BsMerPlatformNo platformNo = platformNoService.getPlatformNo(qrCode.getMerId(), PlatformTypeEnum.type1);
                if (platformNo == null) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
                }
                // 查询终端号
                BsMerPlatformTerm merPlatformTerm = platformTermService.getMerPlatformTerm(platformNo.getId(), "WECHAT_PAY");
                if (merPlatformTerm == null) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
                }
                return ResponseMsgUtil.success(laKaLaTradeService.openidQuery(
                        platformNo.getCupNo(),
                        merPlatformTerm.getTermNo(),
                        body.getString("userAuthCode"),
                        "030304",
                        null,
                        body.getString("appUpIdentifier")
                ));

            } else if (platform.getPlatformType().equals(PlatformTypeEnum.type5.getNumber())) {
                JSONObject unionInfo = tianQueTradeService.getUnionInfo(body.getString("userAuthCode"), body.getString("appUpIdentifier"));
                // 返回格式
                Map<String,Object> param = new HashMap<>();
                param.put("retCode","BBS00000");
                param.put("resMsg","处理成功");

                Map<String,Object> respData = new HashMap<>();
                respData.put("openld", unionInfo.getString("data"));
                respData.put("subOpenld", unionInfo.getString("data"));
                respData.put("userld", unionInfo.getString("data"));

                param.put("respData", respData);
                return ResponseMsgUtil.success(param);

            } else {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的平台");
            }

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

}
