using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace CMSMicroservice.Application.UserCQ.Commands.RefreshToken;

/// <summary>
/// هندلر رفرش توکن - توکن جدید با آخرین اطلاعات کاربر تولید می‌کند
/// </summary>
public class RefreshTokenCommandHandler : IRequestHandler<RefreshTokenCommand, RefreshTokenResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IGenerateJwtToken _generateJwt;

    public RefreshTokenCommandHandler(IApplicationDbContext context, IGenerateJwtToken generateJwt)
    {
        _context = context;
        _generateJwt = generateJwt;
    }

    public async Task<RefreshTokenResponseDto> Handle(RefreshTokenCommand request, CancellationToken cancellationToken)
    {
        try
        {
            // Extract user id from current token
            var handler = new JwtSecurityTokenHandler();
            var jwtToken = handler.ReadJwtToken(request.CurrentToken);
            
            var userIdClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
            if (userIdClaim == null || !long.TryParse(userIdClaim.Value, out var userId))
            {
                return new RefreshTokenResponseDto
                {
                    Success = false,
                    Message = "توکن نامعتبر است",
                    Token = string.Empty
                };
            }

            // Get user with all required relations
            var user = await _context.Users
                .Include(u => u.UserContracts)
                .ThenInclude(u => u.Contract)
                .Include(u => u.UserRoles)
                .ThenInclude(ur => ur.Role)
                .Include(u => u.ClubMembership)
                .FirstOrDefaultAsync(x => x.Id == userId, cancellationToken);

            if (user == null)
            {
                return new RefreshTokenResponseDto
                {
                    Success = false,
                    Message = "کاربر یافت نشد",
                    Token = string.Empty
                };
            }

            // Generate new token
            var newToken = await _generateJwt.GenerateJwtToken(user);

            return new RefreshTokenResponseDto
            {
                Success = true,
                Message = "توکن با موفقیت رفرش شد",
                Token = newToken
            };
        }
        catch (Exception ex)
        {
            return new RefreshTokenResponseDto
            {
                Success = false,
                Message = $"خطا در رفرش توکن: {ex.Message}",
                Token = string.Empty
            };
        }
    }
}
