package com.qs.mp.framework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.admin.domain.Ticket;
import com.qs.mp.admin.domain.TicketBox;
import com.qs.mp.admin.domain.TicketPackage;
import com.qs.mp.admin.service.ITicketBoxService;
import com.qs.mp.admin.service.ITicketPackageService;
import com.qs.mp.admin.service.ITicketService;
import com.qs.mp.channel.domain.ChannelOrder;
import com.qs.mp.channel.service.IChannelOrderService;
import com.qs.mp.channel.service.IChannelUserRelService;
import com.qs.mp.common.enums.*;
import com.qs.mp.common.exception.ServiceException;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.framework.domain.AsyncTask;
import com.qs.mp.framework.mapper.AsyncTaskMapper;
import com.qs.mp.framework.service.IAsyncTaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.user.domain.UserTicketOrder;
import com.qs.mp.user.domain.UserTicketOrderItem;
import com.qs.mp.user.service.IUserTicketOrderItemService;
import com.qs.mp.user.service.IUserTicketOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author quanshu
 * @since 2022-06-07
 */
@Service
public class AsyncTaskServiceImpl extends ServiceImpl<AsyncTaskMapper, AsyncTask> implements IAsyncTaskService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());

    @Autowired
    private IChannelOrderService channelOrderService;

    @Autowired
    private IUserTicketOrderService userTicketService;;

    @Autowired
    private IUserTicketOrderService userTicketOrderService;

    @Autowired
    private ITicketBoxService ticketBoxService;

    @Autowired
    private IUserTicketOrderItemService userTicketOrderItemService;

    @Autowired
    private ITicketService ticketService;

    @Autowired
    private ITicketPackageService ticketPackageService;

    @Autowired
    private IChannelUserRelService channelUserRelService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertAsyncTask(AsyncTaskTypeEnum taskType, String bizId) {
        AsyncTask asyncTask = new AsyncTask();
        asyncTask.setType(taskType.getValue());
        asyncTask.setBizId(bizId);
        return this.save(asyncTask);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void channelConfirmReceipt(AsyncTask asyncTask) {
        // 获取供应商订单编号
        String orderId = asyncTask.getBizId();

        // 查询订单
        ChannelOrder channelOrder = channelOrderService.getById(orderId);
        if (Objects.isNull(channelOrder)) {
            throw new ServiceException("经销商订单不存在,OrderId:" + orderId);
        }

        if (ChannelOrderTypeEnum.RETAIL.equals(channelOrder.getType())) {
            return;
        }

        // 分佣
        userTicketService.commToChannel(orderId, ChannelCommissionResourceEnum.CHANNEL.getValue());
    }

    @Override
    public void ticketPay(AsyncTask asyncTask) {
        String orderId = asyncTask.getBizId();
        UserTicketOrder ticketOrder = userTicketOrderService.getById(orderId);

        TicketBox ticketBox = ticketBoxService.getById(ticketOrder.getBoxId());
        if (ticketBox.getType() == TicketTypeEnum.OFFLINE) {
            // 线下票更新销量，此处不做乐观锁控制，因为不用控制库存
            ticketBoxService.update(
                    new LambdaUpdateWrapper<TicketBox>().set(TicketBox::getSaleQty,
                                    ticketBox.getSaleQty() + 1)
                            .eq(TicketBox::getBoxId, ticketBox.getBoxId()));
        }


        // 更新票组销售数量，此处只做累计，允许并发容错
        List<UserTicketOrderItem> ticketOrderItemList = userTicketOrderItemService.list(new LambdaQueryWrapper<UserTicketOrderItem>()
                .eq(UserTicketOrderItem::getOrderId, orderId));
        for (UserTicketOrderItem orderItem : ticketOrderItemList) {
            Ticket ticket = ticketService.getById(orderItem.getTicketId());
            TicketPackage ticketPackage = ticketPackageService.getById(ticket.getPkgId());
            ticketPackageService.update(new LambdaUpdateWrapper<TicketPackage>()
                    .set(TicketPkgSaleStatusEnum.WAIT_SALE == ticketPackage.getSaleStatus(),
                            TicketPackage::getSaleStatus, TicketPkgSaleStatusEnum.ON_SALE)
                    .set(TicketPkgSaleStatusEnum.ON_SALE == ticketPackage.getSaleStatus()
                                    && ticketPackage.getSaleQty() + 1 >= ticketPackage.getPkgUnit(),
                            TicketPackage::getSaleStatus, TicketPkgSaleStatusEnum.SALE_OUT)
                    .set(TicketPackage::getSaleQty, ticketPackage.getSaleQty() + 1)
                    .eq(TicketPackage::getPkgId, ticketPackage.getPkgId()));
        }

        // 用户关系绑定
        channelUserRelService.bindUser(ticketOrder.getUserId(), ticketOrder.getChannelId());

        if (ticketOrder.getCommStatus() != CommStatusEnum.NO) {
            LogUtil.warn(logger, "收到盲票支付成功任务，订单结佣状态不是未结佣，忽略任务。orderId=" + orderId);
            return;
        }
        userTicketOrderService.commToChannel(orderId, ChannelCommissionResourceEnum.USER.getValue());

    }


    @Override
    public void ticketGenerate(AsyncTask asyncTask) {
        String boxId = asyncTask.getBizId();
        TicketBox ticketBox = ticketBoxService.getById(boxId);
        if (ticketBox.getStatus() != TicketBoxStatusEnum.WAIT ) {
            LogUtil.error(logger, "收到盲票生成任务，票组状态不是待出票，忽略任务。boxId=" + boxId);
            return;
        }
        ticketBoxService.generateTicket(boxId);
    }
}
