package com.snack.server.module.favorite.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.snack.server.common.ResultCode;
import com.snack.server.exception.BusinessException;
import com.snack.server.module.favorite.entity.Favorite;
import com.snack.server.module.favorite.mapper.FavoriteMapper;
import com.snack.server.module.favorite.service.FavoriteService;
import com.snack.server.module.favorite.vo.FavoriteVO;
import com.snack.server.module.product.entity.Product;
import com.snack.server.module.product.mapper.ProductMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户收藏业务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FavoriteServiceImpl implements FavoriteService {

    private final FavoriteMapper favoriteMapper;
    private final ProductMapper productMapper;

    // ==================== 查询 ====================

    @Override
    public Page<FavoriteVO> pageByCurrentUser(Long current, Long size) {
        Long userId = StpUtil.getLoginIdAsLong();
        Page<FavoriteVO> page = new Page<>(current, size);
        return favoriteMapper.selectFavoritePage(page, userId);
    }

    @Override
    public boolean isFavorited(Long productId) {
        Long userId = StpUtil.getLoginIdAsLong();
        return favoriteMapper.selectByUserIdAndProductId(userId, productId) != null;
    }

    @Override
    public Long getFavoriteCount() {
        Long userId = StpUtil.getLoginIdAsLong();
        return favoriteMapper.selectCount(
                new LambdaQueryWrapper<Favorite>().eq(Favorite::getUserId, userId)
        );
    }

    // ==================== 添加 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFavorite(Long productId) {
        Long userId = StpUtil.getLoginIdAsLong();

        // 1. 校验商品是否存在且上架
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new BusinessException(ResultCode.PRODUCT_NOT_EXIST);
        }
        if (product.getStatus() == null || product.getStatus() == 0) {
            throw new BusinessException(ResultCode.PRODUCT_OFF_SHELF);
        }

        // 2. 已收藏则直接返回
        Favorite existing = favoriteMapper.selectByUserIdAndProductId(userId, productId);
        if (existing != null) {
            return;
        }

        // 3. 插入收藏（唯一索引兜底并发场景）
        Favorite favorite = new Favorite();
        favorite.setUserId(userId);
        favorite.setProductId(productId);
        try {
            favoriteMapper.insert(favorite);
            log.info("用户 {} 收藏商品 {}", userId, productId);
        } catch (DuplicateKeyException e) {
            log.warn("用户 {} 重复收藏商品 {}", userId, productId);
        }
    }

    // ==================== 取消收藏 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelFavorite(Long favoriteId) {
        Long userId = StpUtil.getLoginIdAsLong();
        Favorite favorite = favoriteMapper.selectById(favoriteId);
        if (favorite == null || !favorite.getUserId().equals(userId)) {
            throw new BusinessException(1000, "收藏记录不存在或无权访问");
        }
        favoriteMapper.deleteById(favoriteId);
        log.info("用户 {} 取消收藏 id={}", userId, favoriteId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelFavoriteByProductId(Long productId) {
        Long userId = StpUtil.getLoginIdAsLong();
        Favorite favorite = favoriteMapper.selectByUserIdAndProductId(userId, productId);
        if (favorite != null) {
            favoriteMapper.deleteById(favorite.getId());
            log.info("用户 {} 取消收藏商品 {}", userId, productId);
        }
    }
}
