using System.Text;
using CMSMicroservice.Application.Common.Interfaces;
using Microsoft.EntityFrameworkCore;
using CMSMicroservice.Domain.Entities;

namespace CMSMicroservice.Application.UserCQ.Commands.CreateNewOtpToken;

public class CreateNewOtpTokenCommandHandler : IRequestHandler<CreateNewOtpTokenCommand, CreateNewOtpTokenResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IKavenegarService _kavenegarService;
    private readonly ICurrentUserService _currentUserService;

    public CreateNewOtpTokenCommandHandler(IApplicationDbContext context, IKavenegarService kavenegarService, ICurrentUserService currentUserService)
    {
        _context = context;
        _kavenegarService = kavenegarService;
        _currentUserService = currentUserService;
    }

    public async Task<CreateNewOtpTokenResponseDto> Handle(CreateNewOtpTokenCommand request,
        CancellationToken cancellationToken)
    {
        // Generate random 4-digit code
        var random = new Random();
        var code = random.Next(1000, 9999).ToString();

        // Invalidate previous unused tokens for this mobile and purpose
        var existingTokens = await _context.OtpTokens
            .Where(x => x.Mobile == request.Mobile && x.Purpose == request.Purpose && !x.IsUsed)
            .ToListAsync(cancellationToken);

        foreach (var token in existingTokens)
        {
            token.IsUsed = true;
        }

        // Create new OTP token
        var otpToken = new OtpToken
        {
            Mobile = request.Mobile,
            Purpose = request.Purpose,
            Code = code,
            CodeHash = BCrypt.Net.BCrypt.HashPassword(code), // Hash the code for security
            IsUsed = false,
            ExpiresAt = DateTime.UtcNow.AddMinutes(5) // 5 minutes expiry
        };

        _context.OtpTokens.Add(otpToken);
        await _context.SaveChangesAsync(cancellationToken);

        try
        {
            // Send SMS
            var user = await _context.Users
                .Where(x => x.Mobile == request.Mobile)
                .FirstOrDefaultAsync(cancellationToken);

            await _kavenegarService.VerifyLookupAsync(request.Mobile, code);
        }
        catch (Exception)
        {
            // Log error but don't fail the request
            // TODO: Add proper logging
        }

        return new CreateNewOtpTokenResponseDto
        {
            IsSuccess = true,
            Message = "کد تایید با موفقیت ارسال شد",
            ExpiresAt = otpToken.ExpiresAt
        };
    }
}