using FutureMailAPI.Helpers;
using FutureMailAPI.DTOs;
using FutureMailAPI.Models;
using FutureMailAPI.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;

namespace FutureMailAPI.Services
{
    public interface IAuthService
    {
        Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto);
        Task<ApiResponse<AuthResponseDto>> RegisterAsync(UserRegisterDto registerDto);
    }
    
    public class AuthService : IAuthService
    {
        private readonly IUserService _userService;
        private readonly IPasswordHelper _passwordHelper;
        private readonly FutureMailDbContext _context;
        private readonly IConfiguration _configuration;
        
        public AuthService(
            IUserService userService, 
            IPasswordHelper passwordHelper,
            FutureMailDbContext context,
            IConfiguration configuration)
        {
            _userService = userService;
            _passwordHelper = passwordHelper;
            _context = context;
            _configuration = configuration;
        }
        
        public async Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto)
        {
            // 获取用户信息
            var userResult = await _userService.GetUserByUsernameOrEmailAsync(loginDto.UsernameOrEmail);
            
            if (!userResult.Success || userResult.Data == null)
            {
                return ApiResponse<AuthResponseDto>.ErrorResult("用户名或密码错误");
            }
            
            var userDto = userResult.Data;
            
            // 获取原始用户信息用于密码验证
            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Id == userDto.Id);
            
            if (user == null)
            {
                return ApiResponse<AuthResponseDto>.ErrorResult("用户不存在");
            }
            
            // 验证密码
            if (!_passwordHelper.VerifyPassword(loginDto.Password, user.PasswordHash, user.Salt))
            {
                return ApiResponse<AuthResponseDto>.ErrorResult("用户名或密码错误");
            }
            
            // 更新用户响应DTO
            userDto.LastLoginAt = DateTime.UtcNow;
            
            // 生成JWT令牌
            var token = GenerateJwtToken(user);
            var refreshToken = GenerateRefreshToken();
            
            // 保存刷新令牌到用户表
            user.RefreshToken = refreshToken;
            user.RefreshTokenExpiryTime = DateTime.UtcNow.AddDays(7); // 刷新令牌7天过期
            await _context.SaveChangesAsync();
            
            // 创建认证响应DTO
            var authResponse = new AuthResponseDto
            {
                User = userDto,
                Token = token,
                RefreshToken = refreshToken,
                ExpiresIn = 3600 // 1小时，单位秒
            };
            
            return ApiResponse<AuthResponseDto>.SuccessResult(authResponse, "登录成功");
        }
        
        public async Task<ApiResponse<AuthResponseDto>> RegisterAsync(UserRegisterDto registerDto)
        {
            // 检查用户名是否已存在
            var existingUserResult = await _userService.GetUserByUsernameAsync(registerDto.Username);
            
            if (existingUserResult.Success && existingUserResult.Data != null)
            {
                return ApiResponse<AuthResponseDto>.ErrorResult("用户名已存在");
            }
            
            // 检查邮箱是否已存在
            var existingEmailResult = await _userService.GetUserByEmailAsync(registerDto.Email);
            
            if (existingEmailResult.Success && existingEmailResult.Data != null)
            {
                return ApiResponse<AuthResponseDto>.ErrorResult("邮箱已被注册");
            }
            
            // 创建用户
            var createUserResult = await _userService.CreateUserAsync(registerDto);
            
            if (!createUserResult.Success)
            {
                return ApiResponse<AuthResponseDto>.ErrorResult(createUserResult.Message ?? "注册失败");
            }
            
            // 注册成功后，自动登录
            var loginDto = new UserLoginDto
            {
                UsernameOrEmail = registerDto.Username,
                Password = registerDto.Password
            };
            
            return await LoginAsync(loginDto);
        }
        
        private string GenerateJwtToken(User user)
        {
            var jwtSettings = _configuration.GetSection("Jwt");
            var key = Encoding.ASCII.GetBytes(jwtSettings["Key"] ?? throw new InvalidOperationException("JWT密钥未配置"));
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                    new Claim(ClaimTypes.Name, user.Username),
                    new Claim(ClaimTypes.Email, user.Email)
                }),
                Expires = DateTime.UtcNow.AddHours(1),
                Issuer = jwtSettings["Issuer"],
                Audience = jwtSettings["Audience"],
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }

        private string GenerateRefreshToken()
        {
            var randomNumber = new byte[32];
            using var rng = RandomNumberGenerator.Create();
            rng.GetBytes(randomNumber);
            return Convert.ToBase64String(randomNumber);
        }
    }
}