package com.fs.course.service.impl;

import java.math.BigDecimal;
import java.util.*;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fs.common.core.domain.R;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.ip.IpUtils;
import com.fs.core.config.WxPayProperties;
import com.fs.core.utils.OrderCodeUtils;
import com.fs.course.domain.*;
import com.fs.course.mapper.*;
import com.fs.course.param.*;
import com.fs.course.service.IFsUserCourseStudyService;
import com.fs.course.vo.FsUserCourseOrderListPVO;
import com.fs.course.vo.FsUserCourseOrderListUVO;
import com.fs.his.domain.*;
import com.fs.his.dto.PayConfigDTO;
import com.fs.his.enums.FsPackageOrderStatusEnum;
import com.fs.his.enums.FsUserIntegralLogTypeEnum;
import com.fs.his.mapper.*;
import com.fs.his.param.FsPackageOrderDoPayParam;
import com.fs.his.param.FsUserAddIntegralTemplateParam;
import com.fs.his.service.IFsCouponService;
import com.fs.his.service.IFsStorePaymentService;
import com.fs.his.service.IFsUserCouponService;
import com.fs.his.service.IFsUserIntegralLogsService;
import com.fs.huifuPay.domain.HuiFuCreateOrder;
import com.fs.huifuPay.domain.HuifuCreateOrderResult;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.fs.system.service.ISysConfigService;
import com.fs.tzBankPay.TzBankService.TzBankService;
import com.fs.tzBankPay.doman.PayCreateOrder;
import com.fs.tzBankPay.doman.PayCreateOrderResult;
import com.fs.tzBankPay.doman.PayType;
import com.fs.tzBankPay.doman.TzBankResult;
import com.fs.ybPay.domain.CreateWxOrderResult;
import com.fs.ybPay.domain.OrderResult;
import com.fs.ybPay.dto.OrderQueryDTO;
import com.fs.ybPay.dto.WxJspayDTO;
import com.fs.ybPay.service.IPayService;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.gson.Gson;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.course.service.IFsUserCourseOrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

/**
 * 课程订单信息Service业务层处理
 *
 * @author fs
 * @date 2024-05-21
 */
@Service
public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
{
    Logger logger= LoggerFactory.getLogger(getClass());

    @Autowired
    private IPayService payService;
    @Autowired
    private FsUserCourseOrderMapper fsUserCourseOrderMapper;
    @Autowired
    private FsUserMapper fsUserMapper;
    @Autowired
    private FsUserCourseMapper fsUserCourseMapper;
    @Autowired
    private FsUserCourseVideoMapper fsUserCourseVideoMapper;
    @Autowired
    private FsUserIntegralLogsMapper fsUserIntegralLogsMapper;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private IFsStorePaymentService storePaymentService;

    @Autowired
    private FsStorePaymentMapper fsStorePaymentMapper;

    @Autowired
    private HuiFuService huiFuService;

    @Autowired
    private FsStorePaymentErrorMapper fsStorePaymentErrorMapper;

    @Autowired
    private IFsUserCouponService userCouponService;
    @Autowired
    private IFsCouponService couponService;
    @Autowired
    private FsUserCourseStudyMapper fsUserCourseStudyMapper;

    @Autowired
    private FsUserCourseStudyLogMapper fsUserCourseStudyLogMapper;

    @Autowired
    private IPayService ybPayService;

    @Autowired
    private WxPayService wxPayService;

    private WxPayProperties wxPayProperties;
    @Autowired
    private TzBankService tzBankService;
    @Autowired
    private IFsUserIntegralLogsService userIntegralLogsService;
    @Autowired
    private FsUserWxMapper fsUserWxMapper;



    /**
     * 查询课程订单信息
     *
     * @param orderId 课程订单信息主键
     * @return 课程订单信息
     */
    @Override
    public FsUserCourseOrder selectFsUserCourseOrderByOrderId(Long orderId)
    {
        return fsUserCourseOrderMapper.selectFsUserCourseOrderByOrderId(orderId);
    }

    /**
     * 查询课程订单信息列表
     *
     * @param fsUserCourseOrder 课程订单信息
     * @return 课程订单信息
     */
    @Override
    public List<FsUserCourseOrder> selectFsUserCourseOrderList(FsUserCourseOrder fsUserCourseOrder)
    {
        return fsUserCourseOrderMapper.selectFsUserCourseOrderList(fsUserCourseOrder);
    }

    /**
     * 新增课程订单信息
     *
     * @param fsUserCourseOrder 课程订单信息
     * @return 结果
     */
    @Override
    public int insertFsUserCourseOrder(FsUserCourseOrder fsUserCourseOrder)
    {
        fsUserCourseOrder.setCreateTime(DateUtils.getNowDate());
        return fsUserCourseOrderMapper.insertFsUserCourseOrder(fsUserCourseOrder);
    }

    /**
     * 修改课程订单信息
     *
     * @param fsUserCourseOrder 课程订单信息
     * @return 结果
     */
    @Override
    public int updateFsUserCourseOrder(FsUserCourseOrder fsUserCourseOrder)
    {
        fsUserCourseOrder.setUpdateTime(DateUtils.getNowDate());
        return fsUserCourseOrderMapper.updateFsUserCourseOrder(fsUserCourseOrder);
    }

    /**
     * 批量删除课程订单信息
     *
     * @param orderIds 需要删除的课程订单信息主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseOrderByOrderIds(Long[] orderIds)
    {
        return fsUserCourseOrderMapper.deleteFsUserCourseOrderByOrderIds(orderIds);
    }

    /**
     * 删除课程订单信息信息
     *
     * @param orderId 课程订单信息主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseOrderByOrderId(Long orderId)
    {
        return fsUserCourseOrderMapper.deleteFsUserCourseOrderByOrderId(orderId);
    }

    @Override
    public List<FsUserCourseOrderListPVO> selectFsUserCourseOrderListPVO(FsUserCourseOrderParam param) {
        return fsUserCourseOrderMapper.selectFsUserCourseOrderListPVO(param);
    }

    @Override
    public FsUserCourseOrderListPVO selectFsUserCourseOrderVOByOrderId(Long orderId) {
        FsUserCourseOrderListPVO vo = fsUserCourseOrderMapper.selectFsUserCourseOrderVOByOrderId(orderId);
        return vo;
    }

    @Override
    public List<FsUserCourseOrderListUVO> selectFsUserCourseOrderListUVO(FsUserCourseOrderListUParam param) {
        return fsUserCourseOrderMapper.selectFsUserCourseOrderListUVO(param);
    }

    @Override
    @Transactional
    public R createOrder(FsUserCourseOrderCreateParam param) {
        FsUserCourseOrder order  = fsUserCourseOrderMapper.selectFsUserCourseOrderByCourse(param.getUserId(),param.getCourseId());
        if (order!=null&&order.getStatus()==1){
            return R.ok("订单已存在").put("order",order);
        }
        if (order!=null&&order.getStatus()==2){
            return R.error("该课程已购买");
        }
        FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());
        FsUserCourse course = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
        if (course == null) {
            return R.error("课程不存在");
        }
        if (course.getIsShow()==0) {
            return R.error("课程已下架");
        }
        order = new FsUserCourseOrder();
        if (param.getPayType()==null){
            return R.error("非法操作，支付类型不能为空");
        }
        order.setPayPrice(course.getPrice());
        order.setDiscountPrice(course.getPrice().subtract(course.getSellPrice()));
        order.setPayMoney(course.getSellPrice());
        order.setPayType(param.getPayType());
        order.setStatus(1);

        String orderCode =  OrderCodeUtils.getOrderSn();
        if(StringUtils.isEmpty(orderCode)){
            return R.error("订单生成失败，请重试");
        }
        order.setUserId(param.getUserId());
        order.setOrderCode(orderCode);
        order.setCourseId(course.getCourseId());
        order.setCourseName(course.getCourseName());

//        order.setMobile(user.getPhone());
        order.setCreateType(1);
        order.setCreateTime(new Date());
        try {
            if (fsUserCourseOrderMapper.insertFsUserCourseOrder(order) > 0) {
                return R.ok("下单成功").put("order",order);
            } else {
                return R.error("订单创建失败");
            }
        } catch (Exception e) {
            // 异常处理
            return R.error("订单创建失败：" + e.getMessage());
        }
    }

    @Override
    public R createIntegralOrder(FsUserCourseOrderCreateParam param) {
        FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
        if (courseVideo.getCourseSort()==1||courseVideo.getCourseSort()==2){
            return R.error("该小节为免费章节，不可兑换");
        }
        FsUserCourseOrder order = fsUserCourseOrderMapper.selectFsUserCourseOrderByCourseVideo(param.getUserId(),param.getVideoId());
        if (order!=null){
            return R.error("该小节已兑换");
        }
        FsUserCourse course = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
        if (course == null) {
            return R.error("课程不存在");
        }
        if (course.getIsShow()==0) {
            return R.error("课程已下架");
        }
        FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());
        if (course.getIsIntegral()==0){
            return R.error("该小节不允许积分兑换");
        }
        if(user.getIntegral()<course.getIntegral()){
            return R.error("积分不足");
        }
        order = new FsUserCourseOrder();
        order.setIntegral(course.getIntegral());
        order.setCourseVideoId(param.getVideoId());
        order.setPayTime(new Date());
        order.setStatus(2);
        String orderCode =  OrderCodeUtils.getOrderSn();
        if(StringUtils.isEmpty(orderCode)){
            return R.error("订单生成失败，请重试");
        }
        order.setUserId(param.getUserId());
        order.setOrderCode(orderCode);
        order.setCourseId(course.getCourseId());
        order.setCourseName(course.getCourseName());
//        order.setMobile(user.getPhone());
        order.setCreateType(2);
        order.setCreateTime(new Date());
        try {
            // 扣除积分等操作
            if (fsUserCourseOrderMapper.insertFsUserCourseOrder(order) > 0) {
                FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
                FsUserCourseStudy study = fsUserCourseStudyMapper.selectFsUserCourseStudyByAddStudy(param.getUserId(), param.getCourseId());
                if (study == null){
                    study = new FsUserCourseStudy();
                    study.setCourseId(order.getCourseId());
                    study.setUserId(order.getUserId());
                    study.setCreateTime(new Date());
                    fsUserCourseStudyMapper.insertFsUserCourseStudy(study);
                }
                FsUserCourseStudyLog studyLog = fsUserCourseStudyLogMapper.selectFsUserCourseStudyLogByUser(param.getUserId(), param.getVideoId());
                if (studyLog == null){
                    studyLog = new FsUserCourseStudyLog();
                    studyLog.setUserId(order.getUserId());
                    studyLog.setCourseId(order.getCourseId());
                    studyLog.setCourseName(order.getCourseName());
                    studyLog.setVideoId(order.getCourseVideoId());
                    studyLog.setCurrentTimes(0L);
                    studyLog.setStudyId(study.getStudyId());
                    studyLog.setVideoName(video.getTitle());
                    studyLog.setTimes(video.getDuration());
                    studyLog.setIsBuy(1);
                    studyLog.setCreateTime(new Date());
                    fsUserCourseStudyLogMapper.insertFsUserCourseStudyLog(studyLog);
                }
                FsUser userMap=new FsUser();
                userMap.setUserId(user.getUserId());
                userMap.setIntegral(user.getIntegral()-course.getIntegral());
                fsUserMapper.updateFsUser(userMap);
                FsUserIntegralLogs logs = new FsUserIntegralLogs();
                logs.setIntegral(-course.getIntegral());
                logs.setUserId(order.getUserId());
                logs.setBalance(userMap.getIntegral());
                logs.setLogType(9);
                logs.setBusinessId(order.getOrderId().toString());
                logs.setCreateTime(new Date());
                fsUserIntegralLogsMapper.insertFsUserIntegralLogs(logs);
                return R.ok("兑换成功").put("order",order);
            } else {
                return R.error("订单创建失败");
            }
        } catch (Exception e) {
            // 异常处理
            return R.error("订单创建失败：" + e.getMessage());
        }
    }

    @Override
    public R payment(FsUserCourseOrderDoPayParam param) {
        FsUserCourseOrder order = fsUserCourseOrderMapper.selectFsUserCourseOrderByOrderId(param.getOrderId());
        if (order == null) {
            return R.error("订单不存在");
        }
        if (order.getStatus()!=1){
            return R.error("非法操作");
        }
        FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());

        String json = configService.selectConfigByKey("his.pay");
        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);

//        String openId = Objects.isNull(user) ? "" : user.getMaOpenId();
//        if (StringUtils.isBlank(openId)){
//            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
//                    .eq(FsUserWx::getFsUserId, param.getUserId())
//                    .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
//            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
//            if (Objects.nonNull(fsUserWx)){
//                openId = fsUserWx.getOpenId();
//            }
//        }

        String openId = null;
        String appId = param.getAppId();
        if (StringUtils.isNotBlank(appId)) {
            //查询fs_user_wx的openId
            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                    .eq(FsUserWx::getFsUserId, param.getUserId())
                    .eq(FsUserWx::getAppId, appId);
            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
            if (fsUserWx != null) {
                openId = fsUserWx.getOpenId();
            }
        } else {
            appId = payConfigDTO.getAppId();
            openId = Objects.isNull(user) ? "" : user.getMaOpenId();
            if (StringUtils.isBlank(openId)){
                Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                        .eq(FsUserWx::getFsUserId, param.getUserId())
                        .eq(FsUserWx::getAppId, appId);
                FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
                if (Objects.nonNull(fsUserWx)){
                    openId = fsUserWx.getOpenId();
                }
            }
        }

        if(user!=null&& StringUtils.isNotEmpty(openId)) {
            if (order.getPayMoney().compareTo(new BigDecimal(0)) == 0) {
                this.payConfirm(order.getOrderCode(), "", "", "", 2,null,null);
                return R.ok().put("isPay", 1);
            } else {
                String payCode =  OrderCodeUtils.getOrderSn();
                if(StringUtils.isEmpty(payCode)){
                    return R.error("订单生成失败，请重试");
                }
                FsStorePayment storePayment = new FsStorePayment();
                storePayment.setStatus(0);
                storePayment.setPayMode(payConfigDTO.getType());
                storePayment.setBusinessCode(order.getOrderCode());
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(order.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("weixin");
                storePayment.setBusinessType(4);
                storePayment.setRemark("课程订单支付");
                storePayment.setOpenId(openId);
                storePayment.setUserId(user.getUserId());
                storePayment.setBusinessId(order.getOrderId().toString());
                if (storePaymentService.insertFsStorePayment(storePayment) > 0) {
                    if (payConfigDTO.getType().equals("wx")) {
                        //创建微信订单
                        WxPayConfig payConfig = new WxPayConfig();
                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                        payConfig.setAppId(fsPayConfig.getAppId());
                        payConfig.setMchId(fsPayConfig.getWxMchId());
                        payConfig.setMchKey(fsPayConfig.getWxMchKey());
                        payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                        payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                        payConfig.setKeyPath(null);
                        payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
                        wxPayService.setConfig(payConfig);
                        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                        orderRequest.setOpenid(openId);//公众号支付提供用户openid
                        orderRequest.setBody("课程订单支付");
                        orderRequest.setOutTradeNo("course-" + storePayment.getPayCode());
                        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                        //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                        orderRequest.setTradeType("JSAPI");
                        orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                        //调用统一下单接口，获取"预支付交易会话标识"
                        try {
                            WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                            return R.ok().put("data", orderResult).put("type", "wx").put("isPay", 0);
                        } catch (WxPayException e) {
                            e.printStackTrace();
                            throw new CustomException("支付失败" + e.getMessage());
                        }
                    } else if (payConfigDTO.getType().equals("yb")) {
                        WxJspayDTO p = new WxJspayDTO();
                        // 使用setter方法为对象赋值
                        p.setPayMoney(storePayment.getPayMoney().toString());
                        p.setLowOrderId("course-" + storePayment.getPayCode());
                        p.setBody("课程订单支付");
                        p.setIsMinipg("1");
                        p.setOpenId(openId);
                        p.setAttach("");
                        p.setStoreid("0");
                        CreateWxOrderResult wxOrder = payService.createWxOrder(p);
                        if (wxOrder.getStatus().equals("100")) {
                            FsStorePayment mt = new FsStorePayment();
                            mt.setPaymentId(storePayment.getPaymentId());
                            mt.setTradeNo(wxOrder.getUpOrderId());
                            fsStorePaymentMapper.updateFsStorePayment(mt);
                            return R.ok().put("isPay", 0).put("data", wxOrder).put("type", "yb");
                        } else {
                            throw new CustomException("支付失败");
                        }
                    } else if (payConfigDTO.getType().equals("tz")) {
                        PayCreateOrder o = new PayCreateOrder();
                        o.setOrderNo("course" + storePayment.getPayCode()); // 业务系统订单号
                        o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
                        o.setBusinessCstNo(order.getUserId().toString()); // 业务平台客户号
                        String phone = "";
                        if (user.getPhone() != null && user.getPhone().length() > 4) {
                            phone = user.getPhone().substring(user.getPhone().length() - 4);
                        }
                        o.setPayerName("微信用户" + phone);
                        o.setGoodsInfo("课程订单支付"); // 订单信息
                        o.setOpenId(openId);
                        o.setOrderType(4);
                        o.setOrderId(order.getOrderId().toString());
                        TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(o);
                        FsStorePayment mt = new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getBody().getOrderFlowNo());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
                    } else if (payConfigDTO.getType().equals("hf")) {
                        HuiFuCreateOrder o = new HuiFuCreateOrder();
                        o.setTradeType("T_MINIAPP");
                        o.setOpenid(openId);
                        o.setAppId(appId);
                        o.setReqSeqId("course-" + storePayment.getPayCode());
                        o.setTransAmt(storePayment.getPayMoney().toString());
                        o.setGoodsDesc("课程订单支付");
                        o.setAppId(param.getAppId());
                        HuifuCreateOrderResult result = huiFuService.createOrder(o);
                        FsStorePayment mt = new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        mt.setAppId(appId);
                        storePaymentService.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");

                    }

                }
            }
        } else {
            return R.error("用户OPENID不存在");
        }
        return R.error();
    }

    @Override
    public R aliPayment(FsUserCourseOrderDoPayParam param) {
        FsUserCourseOrder order = fsUserCourseOrderMapper.selectFsUserCourseOrderByOrderId(param.getOrderId());
        if (order == null) {
            return R.error("订单不存在");
        }
        if (order.getStatus()!=1){
            return R.error("非法操作");
        }
//        //如果存在优惠券  判断优惠券是否已使用
//        if(order.getUserCouponId()!=null&&order.getUserCouponId()>0){
//            FsUserCoupon userCoupon=userCouponService.selectFsUserCouponById(order.getUserCouponId());
//            if(userCoupon!=null&&!userCoupon.getStatus().equals(0)){
//                return R.error("此订单优惠券已使用，不能支付");
//            }
//        }
        FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());

        String json = configService.selectConfigByKey("his.pay");
        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
        String openId = null;
        String appId = param.getAppId();
        if (StringUtils.isNotBlank(appId)) {
            //查询fs_user_wx的openId
            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                    .eq(FsUserWx::getFsUserId, param.getUserId())
                    .eq(FsUserWx::getAppId, appId);
            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
            if (fsUserWx != null) {
                openId = fsUserWx.getOpenId();
            }
        } else {
            appId = payConfigDTO.getAppId();
            openId = Objects.isNull(user) ? "" : user.getMaOpenId();
            if (StringUtils.isBlank(openId)){
                Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                        .eq(FsUserWx::getFsUserId, param.getUserId())
                        .eq(FsUserWx::getAppId, appId);
                FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
                if (Objects.nonNull(fsUserWx)){
                    openId = fsUserWx.getOpenId();
                }
            }
        }

        if(user!=null){
            if(order.getPayMoney().compareTo(new BigDecimal(0))==1){
                String payCode =  OrderCodeUtils.getOrderSn();
                if(StringUtils.isEmpty(payCode)){
                    return R.error("订单生成失败，请重试");
                }
//                String json = configService.selectConfigByKey("his.pay");
//                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                FsStorePayment storePayment=new FsStorePayment();
                storePayment.setStatus(0);
                storePayment.setPayMode(payConfigDTO.getType());
                storePayment.setBusinessCode(order.getOrderCode());
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(order.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("alipay");
                storePayment.setBusinessType(4);
                storePayment.setRemark("课程订单支付");
//                storePayment.setOpenId(user.getMpOpenId());
                storePayment.setUserId(user.getUserId());
                storePayment.setBusinessId(order.getOrderId().toString());
                if(storePaymentService.insertFsStorePayment(storePayment)>0){

                    if (payConfigDTO.getType().equals("yb")) {
                        return R.error("支付暂不可用!");
                    } else if (payConfigDTO.getType().equals("tz")) {
                        PayCreateOrder o = new PayCreateOrder();
                        o.setOrderNo("course" + storePayment.getPayCode()); // 业务系统订单号
                        o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
                        o.setBusinessCstNo(order.getUserId().toString()); // 业务平台客户号
                        String phone="";
                        if (user.getPhone()!=null&&user.getPhone().length()>4){
                            phone=user.getPhone().substring(user.getPhone().length()-4);
                        }
                        o.setPayerName("微信用户"+phone);
                        o.setGoodsInfo("课堂订单支付"); // 订单信息
//                        o.setOpenId(user.getMpOpenId());
                        o.setOrderType(4);
                        o.setOrderId(order.getOrderId().toString());
                        o.setPayType(Arrays.asList(PayType.ALIPAY_BARCODE_PAYMENT.getCode()));
                        TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(o);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getBody().getOrderFlowNo());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
                    }else if (payConfigDTO.getType().equals("hf")) {
                        HuiFuCreateOrder o = new HuiFuCreateOrder();
                        o.setTradeType("A_NATIVE");
//                        o.setOpenid(user.getMaOpenId());
                        o.setReqSeqId("course-"+storePayment.getPayCode());
                        o.setTransAmt(storePayment.getPayMoney().toString());
                        o.setGoodsDesc("课程订单支付");
                        o.setAppId(appId);
                        HuifuCreateOrderResult result = huiFuService.createOrder(o);
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        mt.setAppId(appId);
                        storePaymentService.updateFsStorePayment(mt);
                        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
                    }
                }
            }
            else{
                this.payConfirm(order.getOrderCode(),"","","",2,null,null);
                return R.ok().put("isPay",1);
            }
        }
        else{
            return R.error("用户不存在");
        }
        return R.error();
    }

    @Override
    @Transactional
    public R payConfirm(String orderSn, String payCode, String tradeNo, String payType, Integer type,String bankTransactionId,String bankSerialNo){
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        try {
            FsUserCourseOrder order=null;
            if(type.equals(1)){
                FsStorePayment storePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
                if (storePayment!=null){
                    if(storePayment.getStatus().equals(0)){
                        FsStorePayment paymentMap=new FsStorePayment();
                        paymentMap.setPaymentId(storePayment.getPaymentId());
                        paymentMap.setStatus(1);
                        paymentMap.setPayTime(new Date());
                        paymentMap.setTradeNo(tradeNo);
                        paymentMap.setBankSerialNo(bankSerialNo);
                        paymentMap.setBankTransactionId(bankTransactionId);
                        if(payType.equals(PayType.WECHAT_MINI_PROGRAM_PAYMENT.getCode())){
                            paymentMap.setPayTypeCode(PayType.WECHAT_MINI_PROGRAM_PAYMENT.name());
                        }
                        else if(payType.equals(PayType.ALIPAY_BARCODE_PAYMENT.getCode())){
                            paymentMap.setPayTypeCode(PayType.ALIPAY_BARCODE_PAYMENT.name());
                        }
                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                        order=fsUserCourseOrderMapper.selectFsUserCourseOrderByOrderId(Long.parseLong(storePayment.getBusinessId()));
                    }
                }
                else{
                    logger.info("支付单号不存在:"+payCode);
                    return R.error("支付单号不存在");
                }
            }
            else if(type.equals(2)){
                order=fsUserCourseOrderMapper.selectFsUserCourseOrderByOrderCode(orderSn);
            }
            if(order.getStatus()!=1){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return R.error("非法操作");
            }

            FsUserCourseOrder map = new FsUserCourseOrder();
            map.setOrderId(order.getOrderId());
            map.setStatus(2);
            map.setPayTime(new Date());
            fsUserCourseOrderMapper.updateFsUserCourseOrder(map);
            FsUserCourseStudy study = fsUserCourseStudyMapper.selectFsUserCourseStudyByAddStudy(order.getCourseId(),order.getUserId());
            if (study==null){
                study=new FsUserCourseStudy();
                study.setCourseId(order.getCourseId());
                study.setUserId(order.getUserId());
                study.setCreateTime(new Date());
                fsUserCourseStudyMapper.insertFsUserCourseStudy(study);
            }
            List<FsUserCourseVideo> videoList = fsUserCourseVideoMapper.selectFsUserCourseListByCourseId(order.getCourseId());
            for (FsUserCourseVideo video:videoList){
                FsUserCourseStudyLog log = fsUserCourseStudyLogMapper.selectFsUserCourseStudyLogByVideo(order.getUserId(),video.getVideoId());
                if (log==null){
                    log = new FsUserCourseStudyLog();
                    log.setUserId(order.getUserId());
                    log.setCourseId(order.getCourseId());
                    log.setCourseName(order.getCourseName());
                    log.setVideoName(video.getTitle());
                    log.setVideoId(video.getVideoId());
                    log.setCurrentTimes(0L);
                    log.setStudyId(study.getStudyId());
                    log.setTimes(video.getDuration());
                    log.setIsBuy(1);
                    log.setCreateTime(new Date());
                    fsUserCourseStudyLogMapper.insertFsUserCourseStudyLog(log);
                }
            }

            // 付费课程订阅
            FsUserAddIntegralTemplateParam integralParam = new FsUserAddIntegralTemplateParam();
            integralParam.setUserId(order.getUserId());
            integralParam.setLogType(FsUserIntegralLogTypeEnum.TYPE_24.getValue());
            integralParam.setBusinessId(order.getOrderId().toString());
            integralParam.setPoints(order.getPayMoney().intValue());
            userIntegralLogsService.addIntegralTemplate(integralParam);

            return R.ok();
        }catch (Exception e){
            logger.info("支付错误:"+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            FsStorePaymentError err = new FsStorePaymentError();
            err.setOrderNo(orderSn);
            err.setOrderFlowNo(tradeNo);
            err.setStatus(0);
            err.setMsg(e.getMessage());
            err.setCreateTime(DateUtils.getNowDate());
            fsStorePaymentErrorMapper.insertFsStorePaymentError(err);
            return R.error();
        }
    }

    @Override
    public R test(Long orderId) {
        FsUserCourseOrder order=fsUserCourseOrderMapper.selectFsUserCourseOrderByOrderId(orderId);
        FsUserCourseOrder map = new FsUserCourseOrder();
        map.setOrderId(order.getOrderId());
        map.setStatus(2);
        map.setPayTime(new Date());
        fsUserCourseOrderMapper.updateFsUserCourseOrder(map);
        FsUserCourseStudy study = fsUserCourseStudyMapper.selectFsUserCourseStudyByAddStudy(order.getCourseId(),order.getUserId());
        if (study==null){
            study=new FsUserCourseStudy();
            study.setCourseId(order.getCourseId());
            study.setUserId(order.getUserId());
            study.setCreateTime(new Date());
            fsUserCourseStudyMapper.insertFsUserCourseStudy(study);
        }
        List<FsUserCourseVideo> videoList = fsUserCourseVideoMapper.selectFsUserCourseListByCourseId(order.getCourseId());
        for (FsUserCourseVideo video:videoList){
            FsUserCourseStudyLog log = fsUserCourseStudyLogMapper.selectFsUserCourseStudyLogByVideo(order.getUserId(),video.getVideoId());
            if (log==null){
                log = new FsUserCourseStudyLog();
                log.setUserId(order.getUserId());
                log.setCourseId(order.getCourseId());
                log.setCourseName(order.getCourseName());
                log.setVideoName(video.getTitle());
                log.setVideoId(video.getVideoId());
                log.setCurrentTimes(0L);
                log.setTimes(video.getDuration());
                log.setCreateTime(new Date());
                log.setIsBuy(1);
                fsUserCourseStudyLogMapper.insertFsUserCourseStudyLog(log);
            }
        }
        return R.ok();
    }

    @Override
    public R computeOrder(FsUserCourseOrderComputeParam param) {
        FsUserCourseOrder order = fsUserCourseOrderMapper.selectFsUserCourseOrderByOrderId(param.getOrderId());
        if (order==null){
            return R.error("订单不存在");
        }
        if (order.getStatus()!=1){
            return R.error("订单状态不正确");
        }
        if (order.getUserCouponId()!=null&&order.getUserCouponId()>0){
            param.setUserCouponId(order.getUserCouponId());
        }
        FsUser user=fsUserMapper.selectFsUserByUserId(order.getUserId());
        if(user!=null){
            Map<String,Object> moneys=computeOrderMoney(order.getPayPrice(),param);
            return R.ok().put("moneys",moneys);
        }
        else{
            return R.error("用户OPENID不存在");
        }
    }

    private Map<String, Object> computeOrderMoney(BigDecimal orderPrice, FsUserCourseOrderComputeParam param) {
        Map<String,Object> moneys=new HashMap<>();
        BigDecimal payPrice=orderPrice;
        BigDecimal payMoney=new BigDecimal(0);
        BigDecimal discountMoney=new BigDecimal(0);
        if(param.getUserCouponId()!=null&&param.getUserCouponId()>0l){
            FsUserCoupon userCoupon=userCouponService.selectFsUserCouponById(param.getUserCouponId());
            if(userCoupon==null){

            }
            if(userCoupon.getStatus()!=0){

            }
            FsCoupon coupon=couponService.selectFsCouponByCouponId(userCoupon.getCouponId());
            if(coupon.getCouponType().equals(1)){
                if(coupon.getMinPrice().compareTo(orderPrice)==1){

                }
                if(coupon.getPrice().compareTo(orderPrice)>=0){
                    payPrice=new BigDecimal(0);
                    discountMoney=coupon.getPrice();
                }
                else{
                    payPrice=orderPrice.subtract(coupon.getPrice());
                    discountMoney=coupon.getPrice();


                }
            }
            else if(coupon.getCouponType().equals(2)){
                payPrice=new BigDecimal(0);
                discountMoney=orderPrice;

            }
            else if(coupon.getCouponType().equals(3)){


            }
            else if(coupon.getCouponType().equals(4)){
                payPrice= orderPrice.multiply(coupon.getRate()).divide(new BigDecimal(100));
                discountMoney=coupon.getPrice().subtract(orderPrice);

            }
            else if(coupon.getCouponType().equals(5)){
                if(coupon.getMinPrice().compareTo(orderPrice)==1){

                }
                if(coupon.getPrice().compareTo(orderPrice)>=0){
                    payPrice=new BigDecimal(0);
                    discountMoney=coupon.getPrice();
                }
                else{
                    payPrice=orderPrice.subtract(coupon.getPrice());
                    discountMoney=coupon.getPrice();

                }

            }
        }
        else{
            payPrice=orderPrice;
            discountMoney=new BigDecimal(0);
        }
        moneys.put("payPrice",payPrice);
        moneys.put("payMoney",payMoney);
        moneys.put("discountMoney",discountMoney);
        return moneys;
    }
}
