package beilv.web.controller.carinformation;

import beilv.admissionticket.domain.AdmissionTicket;
import beilv.admissionticket.service.IAdmissionTicketService;
import beilv.bootacourse.domain.BootACourseBO;
import beilv.bootacourse.service.IBootACourseService;
import beilv.carinformation.domain.CarInformation;
import beilv.carinformation.service.ICarInformationService;
import beilv.common.core.controller.BaseController;
import beilv.common.core.domain.AjaxResult;
import beilv.common.core.page.PageDomain;
import beilv.common.core.page.TableDataInfo;
import beilv.common.core.page.TableSupport;
import beilv.common.utils.DateUtils;
import beilv.common.utils.DictUtils;
import beilv.common.utils.StringUtils;
import beilv.common.utils.uuid.IdUtils;
import beilv.competition.domain.Competition;
import beilv.competition.domain.RedisTask;
import beilv.competition.service.ICompetitionService;
import beilv.system.domain.SysNotice;
import beilv.system.service.ISysConfigService;
import beilv.usermembershipcard.domain.UserMembershipCard;
import beilv.usermembershipcard.service.IUserMembershipCardService;
import beilv.vipCard.domain.VipCard;
import beilv.vipCard.service.IVipCardService;
import beilv.vipCardAmountLog.domain.VipCardAmountLog;
import beilv.vipCardAmountLog.service.IVipCardAmountLogService;
import beilv.vipCardLog.domain.VipCardLog;
import beilv.vipCardLog.service.IVipCardLogService;
import beilv.voucher.domain.BeilvVoucherMember;
import beilv.voucher.service.IBeilvVoucherMemberService;
import beilv.wx.pay.controller.WxPayController;
import beilv.wx.pay.domain.vo.AppPayParam;
import beilv.wx.pay.domain.vo.AppRefundParam;
import cn.hutool.core.lang.Dict;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static beilv.competition.domain.Constant.ORDER_QUEUE;
import static beilv.wx.pay.service.IWxPayService.yuanToFen;

@RestController
@Slf4j
@RequestMapping("/app-api/cardApp")
public class CardAppController extends BaseController {

    @Autowired
    private ICarInformationService carInformationService;

    @Autowired
    private IUserMembershipCardService userMembershipCardService;

    @Autowired
    private IVipCardLogService vipCardLogService;

    @Autowired
    private IVipCardService vipCardService;

    @Autowired
    private IBootACourseService courseService;

    @Autowired
    private ICompetitionService competitionService;

    @Autowired
    private IAdmissionTicketService ticketService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private WxPayController payController;

    @Autowired
    private IVipCardAmountLogService amountLogService;

    @Autowired
    private IBeilvVoucherMemberService voucherMemberService;

    /**
     * 新增充值记录（已废弃，请使用 addOrderLog）
     *
     * @deprecated 使用 addOrderLog 替代
     */
    @Deprecated
    @PostMapping("/addVipCardLog")
    @ResponseBody
    public AjaxResult addSave(@RequestBody VipCardLog vipCardLog) {
        // 兼容旧接口，设置订单类型为充值
        vipCardLog.setOrderType("chongzhi");
        return addOrderLog(vipCardLog);
    }

    /**
     * 新增订单记录（统一接口）
     * 根据 orderType 类型处理不同的订单逻辑
     * - orderType="chongzhi": 充值订单
     * - orderType="yueqiu": 约球订单
     * - orderType="gouka": 购卡订单
     * - orderType="cansai": 参赛订单
     * - orderType="menpiao": 门票订单
     * - 其他类型...
     * <p>
     * 如果是微信支付，会自动调用微信统一下单接口并返回支付参数
     */
    @PostMapping("/addOrderLog")
    @ResponseBody
    public AjaxResult addOrderLog(@RequestBody VipCardLog vipCardLog) {

        if (!"numCard".equals(vipCardLog.getPaymentType()) && !"score".equals(vipCardLog.getPaymentType()) && yuanToFen(vipCardLog.getPracticalMoney()) <= 0) {
            return AjaxResult.error("支付金额无效！");
        }
        String uuid = IdUtils.fastSimpleUUID();
        //设置订单编号
        vipCardLog.setId(uuid);
        //设置下单时间
        vipCardLog.setCreateTime(DateUtils.getNowDate());

        // 根据订单类型进行不同处理
        if ("chongzhi".equals(vipCardLog.getOrderType())) {
            // ========== 充值订单特有逻辑 ==========
            //设置业务id
            vipCardLog.setBusId(IdUtils.fastSimpleUUID());
            //设置支付状态为待支付
            vipCardLog.setPaymentStatus("payment_status_to_be_paid");
            //设置支付方式为微信支付
            vipCardLog.setPaymentType("weChart");
            //设置原价信息为实际支付价格
            vipCardLog.setOriginalPrice(vipCardLog.getPracticalMoney());
            //开启订单定时任务
            createOrderTaskQueue(uuid, "chongzhi", "");

            //判断订单是否使用代金券
            if (StringUtils.isNotEmpty(vipCardLog.getVoucherId())) {
                //修改代金券状态为已使用
                voucherMemberService.updateBeilvVoucherMember(new BeilvVoucherMember(Long.parseLong(vipCardLog.getVoucherId()), "2"));
                //当使用了代金券, 原价为, 实际支付金额+代金券金额
                vipCardLog.setOriginalPrice(vipCardLog.getOriginalPrice().add(vipCardLog.getVoucherPrice()));
            }
        } else {
            // ========== 其他订单类型特有逻辑 ==========
            //订单信息验证
            if (!validateOrder(vipCardLog)) {
                return AjaxResult.error("订单验证失败");
            }

            //只有微信支付才开启订单定时任务
            if ("weChart".equals(vipCardLog.getPaymentType())) {
                //开启订单的定时任务, 超过设定的时间则设置为取消订单
                createOrderTaskQueue(uuid, vipCardLog.getOrderType(), vipCardLog.getBusId());
            }

            //判断订单是否使用代金券
            if (StringUtils.isNotEmpty(vipCardLog.getVoucherId())) {
                //修改代金券状态为已使用
                voucherMemberService.updateBeilvVoucherMember(new BeilvVoucherMember(Long.parseLong(vipCardLog.getVoucherId()), "2"));
            }
        }

        // 如果是微信支付，先调用微信统一下单接口
        if ("weChart".equals(vipCardLog.getPaymentType())) {
            try {
                log.info("开始调用微信统一下单，订单号: {}", uuid);
                AppPayParam appPayParam = new AppPayParam();
                appPayParam.setOrderId(uuid);
                appPayParam.setUserId(Long.valueOf(vipCardLog.getUserId()));
                appPayParam.setTotalPrice(vipCardLog.getOriginalPrice());
                appPayParam.setPayPrice(vipCardLog.getPracticalMoney());
                appPayParam.setDescription(getOrderDescription(vipCardLog.getOrderType()));

                // 调用微信统一下单
                AjaxResult payResult = payController.unifiedOrder(appPayParam);
                if (payResult.isSuccess()) {
                    // 微信支付成功后再写入订单表
                    AjaxResult result = insertVipCardLog(vipCardLog, uuid);
                    
                    // 返回订单ID和支付参数
                    Map<String, Object> data = new HashMap<>();
                    data.put("orderId", uuid);
                    data.put("payParams", payResult.get("data"));
                    return AjaxResult.success("订单创建成功", data);
                } else {
                    log.error("微信统一下单失败，订单号: {}", uuid);
                    return AjaxResult.error("微信统一下单失败: " + payResult.get("msg"));
                }
            } catch (Exception e) {
                log.error("调用微信统一下单异常，订单号: {}", uuid, e);
                return AjaxResult.error("调用微信统一下单异常: " + e.getMessage());
            }
        }

        // 非微信支付直接写入订单表并返回订单创建结果
        return insertVipCardLog(vipCardLog, uuid);
    }

    /**
     * 获取订单描述信息
     */
    private String getOrderDescription(String orderType) {
        switch (orderType) {
            case "chongzhi":
                return "会员卡充值";
            case "yueqiu":
                return "场地预约";
            case "gouka":
                return "购买次卡";
            case "cansai":
                return "赛事报名";
            case "menpiao":
                return "门票购买";
            default:
                return "订单支付";
        }
    }

    /**
     * 充值回调
     */
    @PostMapping("/addVipCardLogCallBack")
    @ResponseBody
    public AjaxResult addVipCardLogCallBack(@RequestBody VipCardLog vipCardLog) {
        int i = vipCardLogService.updateVipCardLogByOrderId(vipCardLog);
        if (i > 0) {
            if ("payment_status_cancelled".equals(vipCardLog.getPaymentStatus())) {
                return payController.cancelOrder(vipCardLog.getId());
            }
            return toAjax(i);
        } else {
            return AjaxResult.error("取消订单失败!");
        }

    }

    /**
     * 其他支付回调
     */
    @PostMapping("/addOrderLogCallBack")
    @ResponseBody
    public AjaxResult addOrderLogCallBack(@RequestBody VipCardLog vipCardLog) {
        int i = vipCardLogService.updateVipCardLogByOrderId(vipCardLog);
        if (i > 0) {
            if ("payment_status_cancelled".equals(vipCardLog.getPaymentStatus())) {
                return payController.cancelOrder(vipCardLog.getId());
            }
            return toAjax(i);
        } else {
            return AjaxResult.error("取消订单失败!");
        }
    }

    /**
     * 查询我的订单
     */
    @GetMapping("/selectOrderList")
    public AjaxResult selectOrderList(VipCardLog vipCardLog) {
        startPage();
        List<VipCardLog> list = vipCardLogService.selectVipCardLogList(vipCardLog);
        return AjaxResult.success(getDataTable(list).getRows());
    }

    /**
     * 小程序退款
     */
    @PostMapping("/refund")
    @ResponseBody
    public AjaxResult refund(@RequestBody VipCardLog vipCardLog) {
        // 1. 先计算退款金额，不更新订单状态和账户信息
        AjaxResult ajaxResult = vipCardLogService.refundById(vipCardLog, true, false);
        if (ajaxResult.get("data") != null) {
            VipCardLog data = (VipCardLog) ajaxResult.get("data");
            AppRefundParam appRefundParam = new AppRefundParam();
            appRefundParam.setOrderId(data.getId());
            appRefundParam.setTotalPrice(data.getOriginalPrice());
            appRefundParam.setRefundAmount(data.getRefundPrice());
            appRefundParam.setUserId(Long.valueOf(data.getUserId()));
            appRefundParam.setDescription(vipCardLog.getDescription());
            try {
                // 2. 执行微信退款
//                payController.refund(appRefundParam);
                // 3. 微信退款成功后，更新订单状态和账户信息
                return vipCardLogService.refundById(vipCardLog, false, true);
            } catch (Exception e) {
                return AjaxResult.error("退款失败!");
            }
        }
        return ajaxResult;
    }

    /**
     * 查询卡种信息列表
     */
    @GetMapping("/cardInformationlist")
    public AjaxResult cardInformationlist(CarInformation carInformation) {
        startPage();
        List<CarInformation> list = carInformationService.selectCarInformationList(carInformation);
        //查询会员等级
        String vipLevel = null;
        VipCard vipCard = vipCardService.selectVipCardByUserId(carInformation.getUserId());
        if (ObjectUtils.isNotEmpty(vipCard)) {
            vipLevel = vipCard.getVipLevel();
        }
        //查询会员折扣
        BigDecimal coefficient = BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(vipLevel) ? "1" : configService.selectConfigByKey(vipLevel)));
        list.forEach(carInformation1 -> carInformation1.setMemberPrice(carInformation1.getOriginalPrice().multiply(coefficient).setScale(2, RoundingMode.HALF_UP)));
        return AjaxResult.success(getDataTable(list).getRows());
    }

    @PostMapping("/getVipCardInfo")
    @ResponseBody
    public AjaxResult getVipCardInfo(@RequestBody VipCardLog vipCardLog) {
        VipCard vipCard = vipCardService.selectVipCardByUserId(vipCardLog.getUserId());
        if (ObjectUtils.isNotEmpty(vipCard)) {
            vipCard.setVipLevel(DictUtils.getDictLabel("vip_level", vipCard.getVipLevel()));
        }
        return AjaxResult.success(vipCard);
    }

    /**
     * 查询用户会员卡列表
     */
    @GetMapping("/getUserCardList")
    public AjaxResult getUserCardList(UserMembershipCard userMembershipCard) {
        startPage();
        userMembershipCard.setState("hasClubCard");
        List<UserMembershipCard> list = userMembershipCardService.selectUserMembershipCardList(userMembershipCard);
        return AjaxResult.success(getDataTable(list).getRows());
    }

    /**
     * 查询约场记录
     */
    @GetMapping("/selectYueQiuList")
    public AjaxResult selectYueChangList(VipCardLog vipCardLog) {
        startPage();
        List<Map<String, Object>> list = vipCardLogService.selectYueQiuList(vipCardLog);
        return AjaxResult.success(getDataTable(list).getRows());
    }

    /**
     * 查询参赛记录  orderType = cansai
     * 查询购买门票记录 orderType = menpiao
     */
    @GetMapping("/selectCompetitionList")
    public AjaxResult selectCanSaiList(VipCardLog vipCardLog) {
        startPage();
        List<Map<String, Object>> list = vipCardLogService.selectCanSaiList(vipCardLog);
        return AjaxResult.success(getDataTable(list).getRows());
    }

    /**
     * 新增订单开启定时任务
     */
    private void createOrderTaskQueue(String uuid, String orderType, String busId) {
        long timeOut = Long.parseLong(configService.selectConfigByKey("order.task.timeout"));
        long timeoutTime = LocalDateTime.now().plus(timeOut, ChronoUnit.MINUTES)
                .atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();

        RedisTask redisTaskApply = new RedisTask(uuid, "", "payment_status_cancelled", orderType, busId);
        redisTemplate.opsForZSet().add(ORDER_QUEUE + uuid, redisTaskApply.toString(), timeoutTime);
    }

    /**
     * 验证订单
     */
    private boolean validateOrder(VipCardLog vipCardLog) {
        String orderType = vipCardLog.getOrderType();
        String paymentType = vipCardLog.getPaymentType();

        boolean flag = true;

        //约球和参赛订单需要验证, 购卡和门票订单无需验证
        if ("yueqiu".equals(orderType)) {
            //约球, 验证场次信息
            flag = validateYueQiuOrder(vipCardLog);
        } else if ("cansai".equals(orderType)) {
            //参赛验证赛事状态和人数
            flag = validateCanSaiOrder(vipCardLog);
        }

        if (!flag) {
            return flag;
        }


        if ("weChart".equals(paymentType)) {
            //如果是微信支付, 订单状态为待支付
            vipCardLog.setPaymentStatus("payment_status_to_be_paid");
        } else {
            //如果是会员卡或次卡, 订单状态为已支付. 支付时间为下单时间
            vipCardLog.setPaymentStatus("payment_status_have_paid");
            vipCardLog.setPaymentTime(vipCardLog.getCreateTime());
            if ("vipCard".equals(paymentType)) {
                //如果是会员卡支付, 验证会员卡信息并扣费. 以及写入记录流水
                return validateVipCardPayment(vipCardLog);
            } else if ("numCard".equals(paymentType)) {
                //如果是次卡支付, 则验证次卡信息并减少次数.
                return validateNumCardPayment(vipCardLog);
            } else {
                log.error("未知支付类型: {}", paymentType);
                return false;
            }
        }
        return true;
    }

    private boolean validateYueQiuOrder(VipCardLog vipCardLog) {
        BootACourseBO courseBO = new BootACourseBO(vipCardLog.getBusId());
        if (!courseService.isOk(courseBO)) {
            return false;
        }
        AdmissionTicket admissionTicket = new AdmissionTicket();
        admissionTicket.setId(vipCardLog.getBusId());
        admissionTicket.setAdmissionTicketStatus("2");
        ticketService.updateBeilvAdmissionTicket(admissionTicket);
        return true;
    }

    private boolean validateCanSaiOrder(VipCardLog vipCardLog) {
        //拉去赛事信息
        Competition competition = competitionService.selectCompetitionById(Integer.valueOf(vipCardLog.getBusId()));
        String competitionState = competition.getCompetitionState();
        if ("competiton_state_3".equals(competitionState)) {
            return false;
        } else if ("competiton_state_4".equals(competitionState)) {
            return false;
        }
        int registrantsNumber = vipCardLogService.getRegistrantsNumber(vipCardLog);
        if (registrantsNumber >= competition.getTeamMax()) {
            return false;
        }
        return true;
    }

    private boolean validateVipCardPayment(VipCardLog vipCardLog) {
        VipCard vipCard = vipCardService.selectVipCardById(vipCardLog.getPaymentId());
        if (vipCard == null) {
            log.error("会员卡不存在: {}", vipCardLog.getPaymentId());
            return false;
        }
        VipCardAmountLog vipCardAmountLog = new VipCardAmountLog(vipCardLog.getUserId(), vipCardLog.getPaymentId(), vipCardLog.getId(), vipCard.getBalance(), vipCardLog.getPracticalMoney().negate(), "1");
        vipCard.setBalance(vipCardAmountLog.getRemainingAmount());
        vipCardService.updateVipCard(vipCard);
        //写入会员卡流水
        vipCardLogService.insertAmountLog(vipCardAmountLog);

        if ("yueqiu".equals(vipCardLog.getOrderType())) {
            //如果是约球订单
            AdmissionTicket admissionTicket = new AdmissionTicket();
            admissionTicket.setId(vipCardLog.getBusId());
            //创建场次定时任务, 到时间自动核销
            ticketService.createTask(admissionTicket);
        }
        return true;
    }

    private boolean validateNumCardPayment(VipCardLog vipCardLog) {
        UserMembershipCard userMembershipCard = userMembershipCardService.selectUserMembershipCardById(Long.valueOf(vipCardLog.getPaymentId()));
        if (userMembershipCard == null) {
            log.error("次卡不存在: {}", vipCardLog.getPaymentId());
            return false;
        }
        if (userMembershipCard.getRemainingNumber() == 0) {
            log.error("次卡次数不足: {}", vipCardLog.getPaymentId());
            return false;
        }
        userMembershipCard.setRemainingNumber(userMembershipCard.getRemainingNumber() - 1);
        userMembershipCardService.updateUserMembershipCard(userMembershipCard);

        if ("yueqiu".equals(vipCardLog.getOrderType())) {
            //如果是约球订单
            AdmissionTicket admissionTicket = new AdmissionTicket();
            admissionTicket.setId(vipCardLog.getBusId());
            //创建场次定时任务, 到时间自动核销
            ticketService.createTask(admissionTicket);
        }
        return true;
    }

    private AjaxResult insertVipCardLog(VipCardLog vipCardLog, String uuid) {
        if (vipCardLogService.insertVipCardLog(vipCardLog) > 0) {
            if ("gouka".equals(vipCardLog.getOrderType())) {
                //如果是购买次卡订单, 拉去卡种信息
                CarInformation carInformation = carInformationService.selectCarInformationById(Long.valueOf(vipCardLog.getBusId()));
                //购卡订单, 支付成功, 生成卡片写入到次卡表
                userMembershipCardService.insertUserMembershipCard(new UserMembershipCard(vipCardLog.getUserId(), vipCardLog.getId(), carInformation.getTotalNumber(), "0", "3", DateUtils.getNowDate(), vipCardLog.getBusId()));
            }
            return AjaxResult.success("操作成功!", uuid);
        } else {
            return toAjax(0);
        }
    }

    /**
     * 查询流水
     * userId
     * amount_type
     */
    @GetMapping("/selectPointsTransactionHistory")
    public AjaxResult selectPointsTransactionHistory(VipCardAmountLog amountLog) {
        startPage();
        HashMap<String, Object> result = new HashMap<>();
        List<Map<String, Object>> maps = amountLogService.selectVipCardAmountLogListAndOrderInfo(amountLog);
        maps.forEach(map -> {
            map.put("createTime", MapUtils.getString(map, "createTime").replace("T", " "));
        });

        result.put("historyList", maps);
        if ("1".equals(amountLog.getAmountType())) {
            result.put("balance", ObjectUtils.isEmpty(vipCardService.selectVipCardByUserId(amountLog.getUserId())) ? 0 : vipCardService.selectVipCardByUserId(amountLog.getUserId()).getBalance());
        } else if ("2".equals(amountLog.getAmountType())) {
            result.put("score", ObjectUtils.isEmpty(vipCardService.selectVipCardByUserId(amountLog.getUserId())) ? 0 : vipCardService.selectVipCardByUserId(amountLog.getUserId()).getScore());
        }
        return AjaxResult.success(result);
    }
}