package com.campus.activity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campus.activity.common.ResultCode;
import com.campus.activity.dto.request.ReviewRequest;
import com.campus.activity.entity.Activity;
import com.campus.activity.entity.CheckIn;
import com.campus.activity.entity.Review;
import com.campus.activity.entity.User;
import com.campus.activity.exception.BusinessException;
import com.campus.activity.mapper.ActivityMapper;
import com.campus.activity.mapper.CheckInMapper;
import com.campus.activity.mapper.ReviewMapper;
import com.campus.activity.service.AuthService;
import com.campus.activity.service.ReviewService;
import com.campus.activity.vo.ReviewVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class ReviewServiceImpl implements ReviewService {

    private final ReviewMapper reviewMapper;
    private final ActivityMapper activityMapper;
    private final CheckInMapper checkInMapper;
    private final AuthService authService;

    @Override
    @Transactional
    public ReviewVO createReview(ReviewRequest request) {
        User currentUser = authService.getCurrentUser();

        Activity activity = activityMapper.selectById(request.getActivityId());
        if (activity == null || activity.getDeleted() == 1) {
            throw new BusinessException(ResultCode.ACTIVITY_NOT_FOUND);
        }

        Review existingReview = reviewMapper.selectOne(
                new LambdaQueryWrapper<Review>()
                        .eq(Review::getUserId, currentUser.getId())
                        .eq(Review::getActivityId, request.getActivityId())
        );

        if (existingReview != null) {
            throw new BusinessException(ResultCode.REVIEW_ALREADY_EXISTS);
        }

        CheckIn checkIn = checkInMapper.selectOne(
                new LambdaQueryWrapper<CheckIn>()
                        .eq(CheckIn::getUserId, currentUser.getId())
                        .eq(CheckIn::getActivityId, request.getActivityId())
        );

        if (checkIn == null) {
            throw new BusinessException(ResultCode.NOT_PARTICIPATED);
        }

        Review review = new Review();
        review.setUserId(currentUser.getId());
        review.setActivityId(request.getActivityId());
        review.setRating(request.getRating());
        review.setContent(request.getContent());

        reviewMapper.insert(review);

        return convertToVO(review, currentUser, activity);
    }

    @Override
    public IPage<ReviewVO> getActivityReviews(Page<Review> page, Long activityId) {
        return reviewMapper.selectActivityReviews(page, activityId);
    }

    @Override
    public IPage<ReviewVO> getMyReviews(Page<Review> page) {
        User currentUser = authService.getCurrentUser();
        return reviewMapper.selectMyReviews(page, currentUser.getId());
    }

    private ReviewVO convertToVO(Review review, User user, Activity activity) {
        ReviewVO vo = new ReviewVO();
        BeanUtils.copyProperties(review, vo);
        vo.setUserName(user.getName());
        vo.setUserAvatar(user.getAvatar());
        vo.setActivityTitle(activity.getTitle());
        return vo;
    }
}