// EN: Merchants Controller for merchant management.
// VI: Controller Merchants để quản lý merchant.

using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MerchantService.API.Application.Commands.Merchants;
using MerchantService.API.Application.Queries.Merchants;

namespace MerchantService.API.Controllers;

/// <summary>
/// EN: Controller for merchant management.
/// VI: Controller để quản lý merchant.
/// </summary>
[ApiController]
[Route("api/v1/merchants")]
[Authorize]
public class MerchantsController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<MerchantsController> _logger;

    public MerchantsController(IMediator mediator, ILogger<MerchantsController> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// EN: Get current merchant's profile.
    /// VI: Lấy profile của merchant hiện tại.
    /// </summary>
    [HttpGet("me")]
    [ProducesResponseType(typeof(MerchantProfileDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetProfile()
    {
        var result = await _mediator.Send(new GetMerchantProfileQuery());
        if (result == null)
        {
            return NotFound(new { message = "Merchant profile not found. Please register first." });
        }
        return Ok(result);
    }

    /// <summary>
    /// EN: Register as a new merchant.
    /// VI: Đăng ký làm merchant mới.
    /// </summary>
    [HttpPost("register")]
    [ProducesResponseType(typeof(RegisterMerchantResult), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<IActionResult> Register([FromBody] RegisterMerchantCommand command)
    {
        try
        {
            var result = await _mediator.Send(command);
            _logger.LogInformation("Merchant registered: {MerchantId}", result.MerchantId);
            return CreatedAtAction(nameof(GetProfile), result);
        }
        catch (Domain.Exceptions.DomainException ex) when (ex.Message.Contains("already has"))
        {
            return Conflict(new { message = ex.Message });
        }
    }

    /// <summary>
    /// EN: Update merchant information.
    /// VI: Cập nhật thông tin merchant.
    /// </summary>
    [HttpPut("me")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> UpdateProfile([FromBody] UpdateMerchantCommand command)
    {
        await _mediator.Send(command);
        return Ok(new { message = "Profile updated successfully" });
    }

    /// <summary>
    /// EN: Submit for verification.
    /// VI: Nộp hồ sơ xác minh.
    /// </summary>
    [HttpPost("me/verify")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> SubmitVerification()
    {
        await _mediator.Send(new SubmitMerchantVerificationCommand());
        return Ok(new { message = "Verification submitted successfully. Please wait for admin approval." });
    }
}

/// <summary>
/// EN: Command to submit merchant for verification.
/// VI: Command để nộp merchant xác minh.
/// </summary>
public record SubmitMerchantVerificationCommand : IRequest<bool>;

/// <summary>
/// EN: Handler for SubmitMerchantVerificationCommand.
/// VI: Handler cho SubmitMerchantVerificationCommand.
/// </summary>
public class SubmitMerchantVerificationCommandHandler : IRequestHandler<SubmitMerchantVerificationCommand, bool>
{
    private readonly Domain.AggregatesModel.MerchantAggregate.IMerchantRepository _merchantRepository;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public SubmitMerchantVerificationCommandHandler(
        Domain.AggregatesModel.MerchantAggregate.IMerchantRepository merchantRepository,
        IHttpContextAccessor httpContextAccessor)
    {
        _merchantRepository = merchantRepository;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<bool> Handle(SubmitMerchantVerificationCommand request, CancellationToken cancellationToken)
    {
        var userIdClaim = _httpContextAccessor.HttpContext?.User.FindFirst("sub")?.Value
            ?? _httpContextAccessor.HttpContext?.User.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value;
        
        if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            throw new Domain.Exceptions.DomainException("User not authenticated");

        var merchant = await _merchantRepository.GetByUserIdAsync(userId, cancellationToken)
            ?? throw new Domain.Exceptions.DomainException("Merchant not found");

        merchant.SubmitForVerification();
        _merchantRepository.Update(merchant);
        await _merchantRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        return true;
    }
}
