using Asp.Versioning;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using FacebookService.API.Application.Commands;
using FacebookService.API.Application.Queries;
using FacebookService.API.Application.Dtos;

namespace FacebookService.API.Controllers;

/// <summary>
/// EN: Controller for Customer management.
/// VI: Controller quản lý Customer.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/customers")]
[Produces("application/json")]
public class CustomersController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<CustomersController> _logger;

    public CustomersController(IMediator mediator, ILogger<CustomersController> logger)
    {
        _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// EN: Get a customer by ID.
    /// VI: Lấy customer theo ID.
    /// </summary>
    [HttpGet("{id:guid}")]
    [ProducesResponseType(typeof(CustomerDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetCustomer(Guid id)
    {
        var customer = await _mediator.Send(new GetCustomerByIdQuery(id));

        if (customer is null)
        {
            return NotFound(new
            {
                success = false,
                error = new { code = "CUSTOMER_NOT_FOUND", message = $"Customer with ID {id} not found" }
            });
        }

        return Ok(new { success = true, data = customer });
    }

    /// <summary>
    /// EN: Get a customer by Facebook User ID.
    /// VI: Lấy customer theo Facebook User ID.
    /// </summary>
    [HttpGet("facebook/{facebookUserId}")]
    [ProducesResponseType(typeof(CustomerDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetCustomerByFacebookId(string facebookUserId)
    {
        var customer = await _mediator.Send(new GetCustomerByFacebookIdQuery(facebookUserId));

        if (customer is null)
        {
            return NotFound(new
            {
                success = false,
                error = new { code = "CUSTOMER_NOT_FOUND", message = $"Customer with Facebook ID {facebookUserId} not found" }
            });
        }

        return Ok(new { success = true, data = customer });
    }

    /// <summary>
    /// EN: Create or update a customer.
    /// VI: Tạo hoặc cập nhật customer.
    /// </summary>
    [HttpPost]
    [ProducesResponseType(typeof(CreateCustomerCommandResult), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> CreateCustomer([FromBody] CreateCustomerRequest request)
    {
        var command = new CreateCustomerCommand(
            request.FacebookUserId,
            request.Name,
            request.Email,
            request.Phone,
            request.ProfilePicUrl,
            request.Locale,
            request.Timezone);

        var result = await _mediator.Send(command);

        return CreatedAtAction(
            nameof(GetCustomer),
            new { id = result.Id },
            new { success = true, data = result });
    }

    /// <summary>
    /// EN: Update customer tags and custom fields.
    /// VI: Cập nhật tags và custom fields của customer.
    /// </summary>
    [HttpPatch("{id:guid}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> UpdateCustomer(Guid id, [FromBody] UpdateCustomerRequest request)
    {
        var command = new UpdateCustomerCommand(id, request.Tags, request.CustomFields);
        var result = await _mediator.Send(command);

        if (!result.Success)
        {
            return NotFound(new
            {
                success = false,
                error = new { code = "CUSTOMER_NOT_FOUND", message = $"Customer with ID {id} not found" }
            });
        }

        return Ok(new { success = true, message = "Customer updated successfully" });
    }
}

#region Request Models

public record CreateCustomerRequest(
    string FacebookUserId,
    string? Name = null,
    string? Email = null,
    string? Phone = null,
    string? ProfilePicUrl = null,
    string? Locale = null,
    string? Timezone = null
);

public record UpdateCustomerRequest(
    IEnumerable<string>? Tags = null,
    Dictionary<string, string>? CustomFields = null
);

#endregion
