package com.emotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.common.PageResult;
import com.emotion.dto.request.reward.RewardCreateRequest;
import com.emotion.dto.request.reward.RewardUpdateRequest;
import com.emotion.dto.response.reward.RewardResponse;
import com.emotion.entity.Reward;
import com.emotion.mapper.RewardMapper;
import com.emotion.service.RewardService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 奖励服务实现类
 * 
 * @author huazhongmin
 * @date 2025-09-08
 */
@Service
public class RewardServiceImpl extends ServiceImpl<RewardMapper, Reward> implements RewardService {

    @Override
    public IPage<Reward> getPage(BasePageRequest request) {
        Page<Reward> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(request.getKeyword())) {
            wrapper.and(w -> w.like(Reward::getName, request.getKeyword())
                    .or().like(Reward::getDescription, request.getKeyword()));
        }
        
        wrapper.eq(Reward::getIsDeleted, 0);

        // 排序
        if (StringUtils.hasText(request.getOrderBy())) {
            if ("asc".equalsIgnoreCase(request.getOrderDirection())) {
                wrapper.orderByAsc(Reward::getCreateTime);
            } else {
                wrapper.orderByDesc(Reward::getCreateTime);
            }
        } else {
            wrapper.orderByDesc(Reward::getCreateTime);
        }
        
        return this.page(page, wrapper);
    }

    @Override
    public PageResult<RewardResponse> getPageWithResponse(BasePageRequest request) {
        IPage<Reward> page = getPage(request);
        List<RewardResponse> responses = page.getRecords().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        PageResult<RewardResponse> pageResult = new PageResult<>();
        pageResult.setRecords(responses);
        pageResult.setCurrent(page.getCurrent());
        pageResult.setSize(page.getSize());
        pageResult.setTotal(page.getTotal());
        pageResult.setPages(page.getPages());
        return pageResult;
    }

    @Override
    public IPage<Reward> getPageByUserId(BasePageRequest request, String userId) {
        Page<Reward> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getCreateBy, userId)
                .eq(Reward::getIsDeleted, 0)
                .orderByDesc(Reward::getCreateTime);
        return this.page(page, wrapper);
    }

    @Override
    public RewardResponse getRewardResponseById(String id) {
        Reward reward = this.getById(id);
        if (reward == null || reward.getIsDeleted() == 1) {
            return null;
        }
        return convertToResponse(reward);
    }

    @Override
    public List<Reward> getByUserId(String userId) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getCreateBy, userId)
               .eq(Reward::getIsDeleted, 0)
               .orderByDesc(Reward::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<Reward> getByRewardType(String rewardType) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getType, rewardType)
               .eq(Reward::getIsDeleted, 0)
               .orderByDesc(Reward::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<Reward> getByUserIdAndRewardType(String userId, String rewardType) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getCreateBy, userId)
                .eq(Reward::getType, rewardType)
               .eq(Reward::getIsDeleted, 0)
               .orderByDesc(Reward::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<Reward> getByStatus(String status) {
        // 这里需要根据实际的status字段来实现
        // 由于Reward实体中没有明确的status字段，这里返回空列表
        return Collections.emptyList();
    }

    @Override
    public List<Reward> getByUserIdAndStatus(String userId, String status) {
        // 这里需要根据实际的status字段来实现
        return Collections.emptyList();
    }

    @Override
    public List<Reward> getByPointsRange(Integer minPoints, Integer maxPoints) {
        // 这里需要根据实际的points字段来实现
        return Collections.emptyList();
    }

    @Override
    public List<Reward> getByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(Reward::getCreateTime, startTime, endTime)
               .eq(Reward::getIsDeleted, 0)
               .orderByDesc(Reward::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<Reward> getByEarnedTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(Reward::getEarnedTime, startTime, endTime)
               .eq(Reward::getIsDeleted, 0)
               .orderByDesc(Reward::getEarnedTime);
        return this.list(wrapper);
    }

    @Override
    public Long countByUserId(String userId) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getCreateBy, userId)
               .eq(Reward::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countByRewardType(String rewardType) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getType, rewardType)
               .eq(Reward::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countByUserIdAndRewardType(String userId, String rewardType) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getCreateBy, userId)
                .eq(Reward::getType, rewardType)
               .eq(Reward::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countByStatus(String status) {
        // 这里需要根据实际的status字段来实现
        return 0L;
    }

    @Override
    public Integer sumPointsByUserId(String userId) {
        // 这里需要根据实际的points字段来实现
        return 0;
    }

    @Override
    public Integer sumPointsByUserIdAndRewardType(String userId, String rewardType) {
        // 这里需要根据实际的points字段来实现
        return 0;
    }

    @Override
    public List<Reward> getRecentByUserId(String userId, Integer limit) {
        LambdaQueryWrapper<Reward> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Reward::getCreateBy, userId)
               .eq(Reward::getIsDeleted, 0)
               .orderByDesc(Reward::getCreateTime)
               .last("LIMIT " + limit);
        return this.list(wrapper);
    }

    @Override
    public List<Reward> getHighPointsRewards(Integer minPoints) {
        // 这里需要根据实际的points字段来实现
        return Collections.emptyList();
    }

    @Override
    public List<Reward> getPendingRewardsByUserId(String userId) {
        // 这里需要根据实际的status字段来实现
        return Collections.emptyList();
    }

    @Override
    public List<Reward> getClaimedRewardsByUserId(String userId) {
        // 这里需要根据实际的status字段来实现
        return Collections.emptyList();
    }

    @Override
    public List<Reward> getExpiredRewards() {
        // 这里需要根据实际的过期时间字段来实现
        return Collections.emptyList();
    }

    @Override
    public boolean updateStatus(String id, String status, LocalDateTime claimedTime) {
        // 这里需要根据实际的status字段来实现
        return false;
    }

    @Override
    public boolean updateExpiredRewards() {
        // 这里需要根据实际的过期时间字段来实现
        return false;
    }

    @Override
    public List<Reward> getBySource(String source) {
        // 这里需要根据实际的source字段来实现
        return Collections.emptyList();
    }

    @Override
    public Reward createReward(String userId, String rewardType, String value,
            String description, String topicId, String achievementId, String icon, String rarity) {
        Reward reward = new Reward();
        reward.setType(rewardType);
        reward.setName(rewardType + "奖励");
        reward.setValue(value);
        reward.setDescription(description);
        reward.setTopicId(topicId);
        reward.setAchievementId(achievementId);
        reward.setIcon(icon);
        reward.setRarity(rarity);
        reward.setCreateBy(userId);
        reward.setEarnedTime(LocalDateTime.now());
        reward.setIsNew(1);

        this.save(reward);
        return reward;
    }

    @Override
    public RewardResponse createRewardWithResponse(RewardCreateRequest request) {
        Reward reward = createReward(
                request.getUserId(),
                request.getRewardType(),
                request.getValue(),
                request.getDescription(),
                request.getTopicId(),
                request.getAchievementId(),
                request.getIcon(),
                request.getRarity());
        return convertToResponse(reward);
    }

    @Override
    public RewardResponse updateRewardWithResponse(RewardUpdateRequest request) {
        Reward reward = this.getById(request.getId());
        if (reward == null || reward.getIsDeleted() == 1) {
            return null;
        }

        // 只更新非空字段
        if (StringUtils.hasText(request.getRewardType())) {
            reward.setType(request.getRewardType());
        }
        if (StringUtils.hasText(request.getValue())) {
            reward.setValue(request.getValue());
        }
        if (StringUtils.hasText(request.getDescription())) {
            reward.setDescription(request.getDescription());
        }
        if (StringUtils.hasText(request.getTopicId())) {
            reward.setTopicId(request.getTopicId());
        }
        if (StringUtils.hasText(request.getAchievementId())) {
            reward.setAchievementId(request.getAchievementId());
        }
        if (StringUtils.hasText(request.getIcon())) {
            reward.setIcon(request.getIcon());
        }
        if (StringUtils.hasText(request.getRarity())) {
            reward.setRarity(request.getRarity());
        }
        if (request.getIsNew() != null) {
            reward.setIsNew(request.getIsNew());
        }

        this.updateById(reward);
        return convertToResponse(reward);
    }

    @Override
    public boolean deleteReward(String id) {
        Reward reward = this.getById(id);
        if (reward == null) {
            return false;
        }

        // 使用 MyBatis-Plus 的 removeById 方法，自动处理逻辑删除
        return this.removeById(id);
    }

    /**
     * 将实体转换为响应对象
     */
    private RewardResponse convertToResponse(Reward reward) {
        if (reward == null) {
            return null;
        }

        RewardResponse response = new RewardResponse();
        BeanUtils.copyProperties(reward, response);
        response.setId(reward.getId());
        if (reward.getCreateTime() != null) {
            response.setCreateTime(reward.getCreateTime().toString());
        }
        if (reward.getUpdateTime() != null) {
            response.setUpdateTime(reward.getUpdateTime().toString());
        }
        return response;
    }
}