using Microsoft.EntityFrameworkCore;
using FutureMailAPI.Data;
using FutureMailAPI.Models;
using FutureMailAPI.DTOs;
using FutureMailAPI.Helpers;

namespace FutureMailAPI.Services
{
    public interface IUserService
    {
        Task<ApiResponse<UserResponseDto>> RegisterAsync(UserRegisterDto registerDto);
        Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto);
        Task<ApiResponse<UserResponseDto>> GetUserByIdAsync(int userId);
        Task<ApiResponse<UserResponseDto>> GetUserByUsernameAsync(string username);
        Task<ApiResponse<UserResponseDto>> GetUserByEmailAsync(string email);
        Task<ApiResponse<UserResponseDto>> GetUserByUsernameOrEmailAsync(string usernameOrEmail);
        Task<ApiResponse<UserResponseDto>> UpdateUserAsync(int userId, UserUpdateDto updateDto);
        Task<ApiResponse<bool>> ChangePasswordAsync(int userId, ChangePasswordDto changePasswordDto);
        Task<ApiResponse<UserResponseDto>> CreateUserAsync(UserRegisterDto registerDto);
    }
    
    public class UserService : IUserService
    {
        private readonly FutureMailDbContext _context;
        private readonly IPasswordHelper _passwordHelper;
        
        public UserService(FutureMailDbContext context, IPasswordHelper passwordHelper)
        {
            _context = context;
            _passwordHelper = passwordHelper;
        }
        
        public async Task<ApiResponse<UserResponseDto>> RegisterAsync(UserRegisterDto registerDto)
        {
            // 检查用户名是否已存在
            var existingUserByUsername = await _context.Users
                .FirstOrDefaultAsync(u => u.Username == registerDto.Username);
                
            if (existingUserByUsername != null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("用户名已存在");
            }
            
            // 检查邮箱是否已存在
            var existingUserByEmail = await _context.Users
                .FirstOrDefaultAsync(u => u.Email == registerDto.Email);
                
            if (existingUserByEmail != null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("邮箱已被注册");
            }
            
            // 生成盐值
            var salt = _passwordHelper.GenerateSalt();
            
            // 创建新用户（使用正确的密码哈希方法）
            var user = new User
            {
                Username = registerDto.Username,
                Email = registerDto.Email,
                PasswordHash = _passwordHelper.HashPassword(registerDto.Password, salt),
                Salt = salt,
                Nickname = registerDto.Nickname ?? registerDto.Username,
                CreatedAt = DateTime.UtcNow
            };
            
            _context.Users.Add(user);
            await _context.SaveChangesAsync();
            
            var userDto = MapToUserResponseDto(user);
            
            return ApiResponse<UserResponseDto>.SuccessResult(userDto, "注册成功");
        }
        
        public async Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto)
        {
            // 查找用户（通过用户名或邮箱）
            User? user;
            
            if (loginDto.UsernameOrEmail.Contains("@"))
            {
                user = await _context.Users
                    .FirstOrDefaultAsync(u => u.Email == loginDto.UsernameOrEmail);
            }
            else
            {
                user = await _context.Users
                    .FirstOrDefaultAsync(u => u.Username == loginDto.UsernameOrEmail);
            }
            
            if (user == null)
            {
                return ApiResponse<AuthResponseDto>.ErrorResult("用户名或密码错误");
            }
            
            // 验证密码
            if (!_passwordHelper.VerifyPassword(loginDto.Password, user.PasswordHash, user.Salt))
            {
                return ApiResponse<AuthResponseDto>.ErrorResult("用户名或密码错误");
            }
            
            // 更新最后登录时间
            user.LastLoginAt = DateTime.UtcNow;
            await _context.SaveChangesAsync();
            
            // 创建认证响应（无token版本）
            var authResponse = new AuthResponseDto
            {
                User = MapToUserResponseDto(user)
            };
            
            return ApiResponse<AuthResponseDto>.SuccessResult(authResponse, "登录成功");
        }
        
        public async Task<ApiResponse<UserResponseDto>> GetUserByIdAsync(int userId)
        {
            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Id == userId);
                
            if (user == null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
            }
            
            var userDto = MapToUserResponseDto(user);
            
            return ApiResponse<UserResponseDto>.SuccessResult(userDto);
        }
        
        public async Task<ApiResponse<UserResponseDto>> GetUserByUsernameAsync(string username)
        {
            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Username == username);
                
            if (user == null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
            }
            
            var userDto = MapToUserResponseDto(user);
            
            return ApiResponse<UserResponseDto>.SuccessResult(userDto);
        }
        
        public async Task<ApiResponse<UserResponseDto>> GetUserByEmailAsync(string email)
        {
            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Email == email);
                
            if (user == null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
            }
            
            var userDto = MapToUserResponseDto(user);
            
            return ApiResponse<UserResponseDto>.SuccessResult(userDto);
        }
        
        public async Task<ApiResponse<UserResponseDto>> GetUserByUsernameOrEmailAsync(string usernameOrEmail)
        {
            User? user;
            
            if (usernameOrEmail.Contains("@"))
            {
                user = await _context.Users
                    .FirstOrDefaultAsync(u => u.Email == usernameOrEmail);
            }
            else
            {
                user = await _context.Users
                    .FirstOrDefaultAsync(u => u.Username == usernameOrEmail);
            }
            
            if (user == null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
            }
            
            var userDto = MapToUserResponseDto(user);
            
            return ApiResponse<UserResponseDto>.SuccessResult(userDto);
        }
        
        public async Task<ApiResponse<UserResponseDto>> UpdateUserAsync(int userId, UserUpdateDto updateDto)
        {
            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Id == userId);
                
            if (user == null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
            }
            
            // 更新用户信息
            if (updateDto.Nickname != null)
            {
                user.Nickname = updateDto.Nickname;
            }
            
            if (updateDto.Avatar != null)
            {
                user.Avatar = updateDto.Avatar;
            }
            
            await _context.SaveChangesAsync();
            
            var userDto = MapToUserResponseDto(user);
            
            return ApiResponse<UserResponseDto>.SuccessResult(userDto, "更新成功");
        }
        
        public async Task<ApiResponse<bool>> ChangePasswordAsync(int userId, ChangePasswordDto changePasswordDto)
        {
            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Id == userId);
                
            if (user == null)
            {
                return ApiResponse<bool>.ErrorResult("用户不存在");
            }
            
            // 验证当前密码
            if (!_passwordHelper.VerifyPassword(changePasswordDto.CurrentPassword, user.PasswordHash, user.Salt))
            {
                return ApiResponse<bool>.ErrorResult("当前密码错误");
            }
            
            // 更新密码
            var salt = _passwordHelper.GenerateSalt();
            user.PasswordHash = _passwordHelper.HashPassword(changePasswordDto.NewPassword, salt);
            user.Salt = salt;
            await _context.SaveChangesAsync();
            
            return ApiResponse<bool>.SuccessResult(true, "密码修改成功");
        }
        
        public async Task<ApiResponse<UserResponseDto>> CreateUserAsync(UserRegisterDto registerDto)
        {
            // 检查用户名是否已存在
            var existingUserByUsername = await _context.Users
                .FirstOrDefaultAsync(u => u.Username == registerDto.Username);
                
            if (existingUserByUsername != null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("用户名已存在");
            }
            
            // 检查邮箱是否已存在
            var existingUserByEmail = await _context.Users
                .FirstOrDefaultAsync(u => u.Email == registerDto.Email);
                
            if (existingUserByEmail != null)
            {
                return ApiResponse<UserResponseDto>.ErrorResult("邮箱已被注册");
            }
            
            // 生成盐值
            var salt = _passwordHelper.GenerateSalt();
            
            // 创建新用户（使用正确的密码哈希方法）
            var user = new User
            {
                Username = registerDto.Username,
                Email = registerDto.Email,
                PasswordHash = _passwordHelper.HashPassword(registerDto.Password, salt),
                Salt = salt,
                Nickname = registerDto.Nickname ?? registerDto.Username,
                CreatedAt = DateTime.UtcNow
            };
            
            _context.Users.Add(user);
            await _context.SaveChangesAsync();
            
            var userDto = MapToUserResponseDto(user);
            
            return ApiResponse<UserResponseDto>.SuccessResult(userDto, "用户创建成功");
        }
        
        private static UserResponseDto MapToUserResponseDto(User user)
        {
            return new UserResponseDto
            {
                Id = user.Id,
                Username = user.Username,
                Email = user.Email,
                Nickname = user.Nickname,
                Avatar = user.Avatar,
                CreatedAt = user.CreatedAt,
                LastLoginAt = user.LastLoginAt
            };
        }
    }
}