package com.ruoyi.ss.vipOrder.service.impl;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import com.github.pagehelper.PageHelper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.SnowFlakeUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.bonus.domain.Bonus;
import com.ruoyi.ss.bonus.service.BonusConverter;
import com.ruoyi.ss.bonus.service.BonusService;
import com.ruoyi.ss.payBill.domain.PayBill;
import com.ruoyi.ss.payBill.domain.PayBillVO;
import com.ruoyi.ss.payBill.domain.bo.RefundSuccessBO;
import com.ruoyi.ss.payBill.domain.enums.PayBillBstType;
import com.ruoyi.ss.payBill.domain.vo.DoPayVO;
import com.ruoyi.ss.payBill.interfaces.AfterPay;
import com.ruoyi.ss.payBill.interfaces.AfterRefund;
import com.ruoyi.ss.payBill.service.PayBillConverter;
import com.ruoyi.ss.payBill.service.PayBillService;
import com.ruoyi.ss.vip.domain.Vip;
import com.ruoyi.ss.vip.domain.VipVO;
import com.ruoyi.ss.vip.service.VipConverter;
import com.ruoyi.ss.vip.service.VipService;
import com.ruoyi.ss.vipOrder.domain.VipOrder;
import com.ruoyi.ss.vipOrder.domain.VipOrderQuery;
import com.ruoyi.ss.vipOrder.domain.VipOrderVO;
import com.ruoyi.ss.vipOrder.domain.bo.AddPayVipOrderBO;
import com.ruoyi.ss.vipOrder.domain.enums.VipOrderStatus;
import com.ruoyi.ss.vipOrder.domain.vo.AddAndPayVO;
import com.ruoyi.ss.vipOrder.mapper.VipOrderMapper;
import com.ruoyi.ss.vipOrder.service.VipOrderConverter;
import com.ruoyi.ss.vipOrder.service.VipOrderService;
import com.ruoyi.ss.vipOrder.service.VipOrderValidator;

/**
 * 会员订单Service业务层处理
 *
 * @author ruoyi
 * @date 2025-01-16
 */
@Service
public class VipOrderServiceImpl implements VipOrderService, AfterPay, AfterRefund
{
    @Autowired
    private VipOrderMapper vipOrderMapper;

    @Autowired
    private VipOrderValidator vipOrderValidator;

    @Autowired
    private VipOrderConverter vipOrderConverter;

    @Autowired
    private PayBillConverter payBillConverter;

    @Autowired
    private PayBillService payBillService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private VipService vipService;

    @Autowired
    private VipConverter vipConverter;

    @Autowired
    private BonusService bonusService;

    @Autowired
    private BonusConverter bonusConverter;

    @Autowired
    private ScheduledExecutorService scheduledExecutorService;

    /**
     * 查询会员订单
     *
     * @param id 会员订单主键
     * @return 会员订单
     */
    @Override
    public VipOrderVO selectVipOrderById(Long id)
    {
        return vipOrderMapper.selectVipOrderById(id);
    }

    /**
     * 查询会员订单列表
     *
     * @param vipOrder 会员订单
     * @return 会员订单
     */
    @Override
    public List<VipOrderVO> selectVipOrderList(VipOrderQuery vipOrder)
    {
        return vipOrderMapper.selectVipOrderList(vipOrder);
    }

    /**
     * 新增会员订单
     *
     * @param vipOrder 会员订单
     * @return 结果
     */
    @Override
    public int insertVipOrder(VipOrder vipOrder)
    {
        vipOrder.setCreateTime(DateUtils.getNowDate());
        vipOrder.setOrderNo(String.valueOf(SnowFlakeUtil.newId()));
        return vipOrderMapper.insertVipOrder(vipOrder);
    }

    /**
     * 修改会员订单
     *
     * @param vipOrder 会员订单
     * @return 结果
     */
    @Override
    public int updateVipOrder(VipOrder vipOrder)
    {
        return vipOrderMapper.updateVipOrder(vipOrder);
    }

    /**
     * 批量删除会员订单
     *
     * @param ids 需要删除的会员订单主键
     * @return 结果
     */
    @Override
    public int deleteVipOrderByIds(Long[] ids)
    {
        return vipOrderMapper.deleteVipOrderByIds(ids);
    }

    /**
     * 删除会员订单信息
     *
     * @param id 会员订单主键
     * @return 结果
     */
    @Override
    public int deleteVipOrderById(Long id)
    {
        return vipOrderMapper.deleteVipOrderById(id);
    }

    @Override
    public AddAndPayVO addAndPay(AddPayVipOrderBO bo) {
        // 校验
        vipOrderValidator.preAddAndPay(bo);

        // 结果
        AddAndPayVO result = new AddAndPayVO();

        // 转为订单数据
        VipOrder order = vipOrderConverter.toOrder(bo);
        ServiceUtil.assertion(order == null, "订单数据为空");
        bo.setOrder(order);

        // 操作数据库
        transactionTemplate.execute(status -> {
            // 创建订单
            int insert = this.insertVipOrder(order);
            ServiceUtil.assertion(insert != 1, "创建订单失败");

            // 创建并支付
            PayBill pay = payBillConverter.toPoByVipOrderBO(bo);
            ServiceUtil.assertion(pay == null, "支付单数据为空");
            DoPayVO payResult = payBillService.createPayBill(pay);
            ServiceUtil.assertion(payResult == null, "调起支付失败");

            // 构造结果集
            result.setPayParams(payResult.getPayParams());
            result.setPayNo(pay.getPayNo());
            result.setOrderNo(order.getOrderNo());

            return insert;
        });

        return result;
    }

    @Override
    public int onPaySuccess(PayBillVO pay) {
        if (pay == null) {
            return 0;
        }
        VipOrderVO order = selectVipOrderById(pay.getBstId());
        if (order == null) {
            return 0;
        }
        // 若已经为成功，则直接返回 1
        if (VipOrderStatus.SUCCESS.getStatus().equals(order.getStatus())) {
            return 1;
        }

        Integer result = transactionTemplate.execute(status -> {
            // 更新订单状态
            VipOrder data = new VipOrder();
            data.setStatus(VipOrderStatus.SUCCESS.getStatus());
            data.setPayId(pay.getPayId());
            data.setPayNo(pay.getPayNo());
            VipOrderQuery query = new VipOrderQuery();
            query.setId(order.getId());
            query.setStatus(VipOrderStatus.WAIT_PAY.getStatus());
            int update = this.updateByQuery(data, query);

            if (update == 1) {
                // 续费VIP
                this.renewalVip(order);

                // 创建分成数据
                List<Bonus> bonusList = bonusConverter.toPoList(order);
                int insertBonus = bonusService.batchInsert(bonusList);
                ServiceUtil.assertion(insertBonus != bonusList.size(), "创建分成失败");
            }

            return update;
        });

        // 立即执行一次分成
        if (result != null && result == 1) {
            scheduledExecutorService.schedule(()-> {
                bonusService.payBonusBeforeTime(LocalDateTime.now());
            }, 3, TimeUnit.SECONDS);
        }

        return result == null ? 0 : result;
    }

    private int renewalVip(VipOrderVO order) {
        // 续费兼容的VIP时长
        VipVO vip =  vipService.selectUserSameVip(
                order.getUserId(),
                order.getLevelId(),
                order.getLevelDiscount(),
                order.getLevelStoreId(),
                order.getLevelLimitType(),
                order.getLevelLimitCount()
        );
        // 可兼容操作
        if (vip != null ) {
            int renewal = vipService.renewal(vip.getId(), order.getLevelTime(), order.getLevelLimitTotal());
            ServiceUtil.assertion(renewal != 1, "续费ID为%s的VIP失败", vip.getId());
            return renewal;
        }
        // 不兼容操作
        else {
            Vip po = vipConverter.toPo(order);
            int insertVip = vipService.insertVip(po);
            ServiceUtil.assertion(insertVip != 1, "新建VIP失败");
            return insertVip;
        }
    }

    private int updateByQuery(VipOrder data, VipOrderQuery query) {
        return vipOrderMapper.updateByQuery(data, query);
    }

    @Override
    public int onRefundSuccess(RefundSuccessBO bo) {
        return 0;
    }

    @Override
    public int refreshPayResult(Long id) {
        if (id == null) {
            return 0;
        }
        return payBillService.refreshPayResult(PayBillBstType.VIP_ORDER, id);
    }

    @Override
    public int refreshPayResult(String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            return 0;
        }
        VipOrderVO order = selectVipOrderByOrderNo(orderNo);
        if (order == null || order.getId() == null) {
            return 0;
        }
        return payBillService.refreshPayResult(PayBillBstType.VIP_ORDER, order.getId());
    }

    // 根据订单号查询订单
    private VipOrderVO selectVipOrderByOrderNo(String orderNo) {
        VipOrderQuery query = new VipOrderQuery();
        query.setEqOrderNo(orderNo);
        return this.selectOne(query);
    }

    // 根据查询条件查询一个订单
    private VipOrderVO selectOne(VipOrderQuery query) {
        PageHelper.startPage(1, 1);
        List<VipOrderVO> list = this.selectVipOrderList(query);
        return CollectionUtils.firstElement(list);
    }
}
