package com.ylx.massage.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ylx.common.core.domain.model.WxLoginUser;
import com.ylx.common.exception.ServiceException;
import com.ylx.common.utils.StringUtils;
import com.ylx.lottery.domain.LotteryCountLog;
import com.ylx.lottery.domain.vo.LocalActivityTableVO;
import com.ylx.lottery.domain.vo.LotteryActivityVO;
import com.ylx.lottery.service.LotteryCountLogService;
import com.ylx.lottery.service.LotteryCountService;
import com.ylx.massage.domain.CommentUserAudit;
import com.ylx.massage.domain.TCommentUser;
import com.ylx.massage.domain.TOrder;
import com.ylx.massage.domain.TWxUser;
import com.ylx.massage.enums.OrderStatusEnum;
import com.ylx.massage.mapper.TCommentUserMapper;
import com.ylx.massage.service.TCommentUserAuditService;
import com.ylx.massage.service.TCommentUserService;
import com.ylx.massage.service.TOrderService;
import com.ylx.massage.service.TWxUserService;
import com.ylx.point.domain.dto.ApiAddPointsDTO;
import com.ylx.point.service.IPointAccountService;
import com.ylx.usercenter.domain.dto.UnifiedUserCenterDTO;
import com.ylx.usercenter.service.UnifiedUserCenterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 用户评论表(TCommentUser)表服务实现类
 *
 * @author makejava
 * @since 2024-08-08 10:32:08
 */
@Slf4j
@Service("tCommentUserService")
public class TCommentUserServiceImpl extends ServiceImpl<TCommentUserMapper, TCommentUser> implements TCommentUserService {

    @Resource
    private TOrderService orderService;

    @Resource
    private TCommentUserAuditService commentUserAuditService;

    @Resource
    private TCommentUserMapper tCommentUserMapper;
    @Resource
    private LotteryCountService lotteryCountService;
    @Resource
    private LotteryCountLogService lotteryCountLogService;
    @Resource
    private UnifiedUserCenterService unifiedUserCenterService;
    @Resource
    private IPointAccountService pointAccountService;
    @Resource
    private TWxUserService wxUserService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveComment(TCommentUser comment, WxLoginUser wxLoginUser) {
        //订单ID不能为空
        if (StringUtils.isBlank(comment.getOrderId())) {
            throw new ServiceException("订单id不能为空");
        }
        //判断订单是否存在
        TOrder order1 = orderService.getById(comment.getOrderId());
        if (order1 == null) {
            throw new ServiceException("订单不存在");
        }
        if (StringUtils.isBlank(comment.getOrderNo())) {
            throw new ServiceException("订单号不能为空");
        }
        if (StringUtils.isBlank(comment.getText())) {
            throw new ServiceException("评论内容不能空");
        }
        if (StringUtils.isBlank(comment.getJsId())) {
            throw new ServiceException("技师id不能空");
        }
        if (StringUtils.isBlank(comment.getName())) {
            throw new ServiceException("技师姓名不能空");
        }
        comment.setOpenId(wxLoginUser.getCOpenid());
        //comment.setOpenId("o-HEJ6RAjBDjFvuZcAdHRX8mIZXw");
        comment.setCommentTime(new Date());
        this.save(comment);

        //向用户评论审核表中插入数据
        CommentUserAudit commentUserAudit = new CommentUserAudit();
        commentUserAudit.setCommentId(comment.getId());
        commentUserAudit.setOrderNo(comment.getOrderNo());
        commentUserAudit.setText(comment.getText());
        //默认审核状态为待审核
        commentUserAudit.setAuditStatus(0);
        commentUserAudit.setCreateTime(new Date());
        commentUserAudit.setUpdateTime(new Date());
        commentUserAudit.setIsDelete(0);
        commentUserAuditService.save(commentUserAudit);

        TOrder order = new TOrder();
        //修改订单状态（已完成）
        order.setnStatus(OrderStatusEnum.COMPLETE.getCode());
        order.setcId(comment.getOrderId());
        boolean updateOrderSuccess = orderService.updateById(order);
        if (!updateOrderSuccess) {
            throw new ServiceException("订单状态更新失败");
        }

        // 评价有礼 —— 发放抽奖次数日志
        grantLotteryCountForComment(wxLoginUser);

        // 已绑定一账通 → 异步同步抽奖次数
        syncLotteryCountIfNeeded(wxLoginUser.getId());

        return true;
    }

    @Override
    public List<TCommentUser> selectAll(TCommentUser tCommentUser) {
        return tCommentUserMapper.selectAll(tCommentUser);
    }

    /**
     * 评价有礼发放抽奖次数
     */
    private void grantLotteryCountForComment(WxLoginUser wxLoginUser) {
        List<LotteryActivityVO> activityList = lotteryCountService.queryActivityRules();
        if (CollUtil.isEmpty(activityList)) {
            return;
        }

        for (LotteryActivityVO activity : activityList) {
            // 处理积分表
            List<LocalActivityTableVO> pointTables = activity.getGyyPointTables();
            if (CollUtil.isNotEmpty(pointTables)) {
                for (LocalActivityTableVO table : pointTables) {
                    ApiAddPointsDTO dto = new ApiAddPointsDTO();
                    dto.setUserId(wxLoginUser.getId());
                    dto.setPoints(table.getPointNumber());
                    pointAccountService.apiAddPoints(dto);
                }
            }

            // 非积分表、任务奖励类型（参与规则=3）
            if (ObjectUtil.notEqual(activity.getParticipationRules(), 3)) {
                continue;
            }

            List<LocalActivityTableVO> localTables = activity.getLocalActivityTables();
            if (CollUtil.isEmpty(localTables)) {
                continue;
            }

            String activityUrl = activity.getActivityUrl();

            // 类型=4 → 评价有礼
            for (LocalActivityTableVO table : localTables) {
                if (ObjectUtil.equals(table.getType(), "4")) {
                    table.setActivityUrl(activityUrl);
                    table.setActivityId(activity.getId());
                    saveLotteryLog(wxLoginUser, table, 1);
                }
            }
        }
    }

    /**
     * 统一保存抽奖次数日志
     */
    private void saveLotteryLog(WxLoginUser wxLoginUser, LocalActivityTableVO table, Integer lotteryNum) {
        LotteryCountLog log = new LotteryCountLog();
        log.setOpenId(wxLoginUser.getCOpenid());
        log.setUserId(wxLoginUser.getId());
        log.setUserPhone(wxLoginUser.getCPhone());
        log.setActivityType(2); // 任务奖励
        log.setLocalActivityTableId(table.getActivityId());
        log.setLotteryNum(lotteryNum);
        log.setReceiveTime(new Date());
        log.setIsDelete("0");
        log.setStatus(0); // 未同步
        log.setIsLottery(0);
        log.setType(3);
        log.setActivityUrl(table.getActivityUrl());
        lotteryCountLogService.save(log);
    }

    private void syncLotteryCountIfNeeded(String id) {

        // 避免用户绑定本地生活用户后，token中数据未能更新，导致不能同步抽奖次数
        TWxUser user = this.wxUserService.getById(id);
        if (ObjectUtil.isNull(user)) {
            throw new ServiceException("用户不存在");
        }

        if (ObjectUtil.equals(user.getIsBind(), 1)
                && StringUtils.isNotBlank(user.getLocalLiveUserId())) {

            UnifiedUserCenterDTO dto = new UnifiedUserCenterDTO();
            dto.setSourceUserId(user.getLocalLiveUserId());
            dto.setTargetUserId(user.getId());

            // 👇 加上这个 if 判断，只有当当前存在活跃事务时，才去注册 afterCommit 回调
            if (TransactionSynchronizationManager.isSynchronizationActive()) {
                TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                    @Override
                    public void afterCommit() {
                        // 事务提交完成！现在调用异步，一定能查到数据
                        unifiedUserCenterService.syncLotteryCount(dto);
                    }
                });
            } else {
                // 👇 兜底逻辑：如果事务没开启（比如同类自调用导致失效），就直接同步执行，避免报错
                log.warn("当前没有活跃事务，无法注册 afterCommit 回调，将直接同步执行抽奖次数同步！");
                unifiedUserCenterService.syncLotteryCount(dto);
            }

        }
    }
}