using CMSMicroservice.Application.Common.Exceptions;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities;
using CMSMicroservice.Domain.Entities.Payment;
using CMSMicroservice.Domain.Enums;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace CMSMicroservice.Application.ManualPaymentCQ.Commands.CreateManualPayment;

public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPaymentCommand, long>
{
    private readonly IApplicationDbContext _context;
    private readonly ICurrentUserService _currentUser;
    private readonly ILogger<CreateManualPaymentCommandHandler> _logger;

    public CreateManualPaymentCommandHandler(
        IApplicationDbContext context,
        ICurrentUserService currentUser,
        ILogger<CreateManualPaymentCommandHandler> logger)
    {
        _context = context;
        _currentUser = currentUser;
        _logger = logger;
    }

    public async Task<long> Handle(
        CreateManualPaymentCommand request,
        CancellationToken cancellationToken)
    {
        try
        {
            _logger.LogInformation(
                "Creating manual payment for UserId: {UserId}, Amount: {Amount}, Type: {Type}",
                request.UserId,
                request.Amount,
                request.Type
            );

            // 1. بررسی وجود کاربر
            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);

            if (user == null)
            {
                _logger.LogWarning("User not found: {UserId}", request.UserId);
                throw new NotFoundException(nameof(User), request.UserId);
            }

            // 2. بررسی Admin فعلی
            var currentUserId = _currentUser.UserId;
            if (string.IsNullOrEmpty(currentUserId))
            {
                throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
            }

            if (!long.TryParse(currentUserId, out var requestedById))
            {
                throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
            }

            // 3. ایجاد ManualPayment
            var manualPayment = new ManualPayment
            {
                UserId = request.UserId,
                Amount = request.Amount,
                Type = request.Type,
                Description = request.Description,
                ReferenceNumber = request.ReferenceNumber,
                Status = ManualPaymentStatus.Pending,
                RequestedBy = requestedById
            };

            _context.ManualPayments.Add(manualPayment);
            await _context.SaveChangesAsync(cancellationToken);

            _logger.LogInformation(
                "Manual payment created successfully. Id: {Id}, UserId: {UserId}, RequestedBy: {RequestedBy}",
                manualPayment.Id,
                request.UserId,
                requestedById
            );

            return manualPayment.Id;
        }
        catch (Exception ex)
        {
            _logger.LogError(
                ex,
                "Error creating manual payment for UserId: {UserId}",
                request.UserId
            );
            throw;
        }
    }
}
