package com.example.demo.service;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;

@Service
public class UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Transactional
    public User register(String username, String email, String rawPassword) {
        if (userRepository.existsByUsername(username)) {
            throw new IllegalArgumentException("用户名已存在");
        }
        if (userRepository.existsByEmail(email)) {
            throw new IllegalArgumentException("邮箱已被使用");
        }
        User user = new User();
        user.setUsername(username);
        user.setEmail(email);
        user.setPasswordHash(rawPassword);
        // 注册时默认为普通用户
        user.setRole("ROLE_USER");
        return userRepository.save(user);
    }

    @Transactional(readOnly = true)
    public java.util.List<User> findAll() {
        return userRepository.findAll();
    }

    @Transactional(readOnly = true)
    public User findById(Long id) {
        return userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("用户不存在"));
    }

    @Transactional(readOnly = true)
    public User findByUsername(String username) {
        return userRepository.findByUsername(username).orElseThrow(() -> new IllegalArgumentException("用户不存在"));
    }

    @Transactional
    public User create(String username, String email, String rawPassword) {
        return register(username, email, rawPassword);
    }

    @Transactional
    public User update(Long id, String username, String email, String rawPasswordNullable) {
        return update(id, username, email, rawPasswordNullable, null);
    }

    @Transactional
    public User update(Long id, String username, String email, String rawPasswordNullable, String role) {
        User user = findById(id);
        if (!user.getUsername().equals(username) && userRepository.existsByUsername(username)) {
            throw new IllegalArgumentException("用户名已存在");
        }
        if (!user.getEmail().equals(email) && userRepository.existsByEmail(email)) {
            throw new IllegalArgumentException("邮箱已被使用");
        }
        user.setUsername(username);
        user.setEmail(email);
        if (role != null && !role.isBlank()) {
            user.setRole(role);
        }
        if (rawPasswordNullable != null && !rawPasswordNullable.isBlank()) {
            user.setPasswordHash(rawPasswordNullable);
        }
        return userRepository.save(user);
    }

    @Transactional
    public void delete(Long id) {
        userRepository.deleteById(id);
    }

    /**
     * 检查密码是否匹配（明文比较）
     */
    public boolean checkPassword(String rawPassword, String storedPassword) {
        return rawPassword.equals(storedPassword);
    }

    /**
     * 根据邮箱查找用户
     */
    @Transactional(readOnly = true)
    public User findByEmail(String email) {
        return userRepository.findByEmail(email).orElse(null);
    }

    /**
     * 保存用户
     */
    @Transactional
    public User save(User user) {
        return userRepository.save(user);
    }

    /**
     * 增加用户积分
     */
    @Transactional
    public User addPoints(Long userId, Integer points) {
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        int newPoints = user.getPoints() + points;
        if (newPoints < 0) {
            throw new RuntimeException("积分不能为负数");
        }
        
        user.setPoints(newPoints);
        return userRepository.save(user);
    }

    /**
     * 减少用户积分
     */
    @Transactional
    public User deductPoints(Long userId, Integer points) {
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        int newPoints = user.getPoints() - points;
        if (newPoints < 0) {
            throw new RuntimeException("积分不足");
        }
        
        user.setPoints(newPoints);
        return userRepository.save(user);
    }

    /**
     * 获取用户积分
     */
    @Transactional(readOnly = true)
    public Integer getUserPoints(Long userId) {
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new RuntimeException("用户不存在"));
        return user.getPoints();
    }
}


