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

namespace MktXService.API.Controllers;

/// <summary>
/// EN: Controller for Sample CRUD operations using CQRS pattern.
/// VI: Controller cho các thao tác CRUD Sample sử dụng pattern CQRS.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[Produces("application/json")]
public class SamplesController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<SamplesController> _logger;

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

    /// <summary>
    /// EN: Get all samples.
    /// VI: Lấy tất cả samples.
    /// </summary>
    /// <returns>EN: List of samples / VI: Danh sách samples</returns>
    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<SampleViewModel>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetSamples()
    {
        var samples = await _mediator.Send(new GetSamplesQuery());
        return Ok(new { success = true, data = samples });
    }

    /// <summary>
    /// EN: Get a sample by ID.
    /// VI: Lấy một sample theo ID.
    /// </summary>
    /// <param name="id">EN: Sample ID / VI: ID sample</param>
    /// <returns>EN: Sample details / VI: Chi tiết sample</returns>
    [HttpGet("{id:guid}")]
    [ProducesResponseType(typeof(SampleViewModel), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetSample(Guid id)
    {
        var sample = await _mediator.Send(new GetSampleQuery(id));

        if (sample is null)
        {
            return NotFound(new
            {
                success = false,
                error = new
                {
                    code = "SAMPLE_NOT_FOUND",
                    message = $"Sample with ID {id} not found / Sample với ID {id} không tìm thấy"
                }
            });
        }

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

    /// <summary>
    /// EN: Create a new sample.
    /// VI: Tạo một sample mới.
    /// </summary>
    /// <param name="request">EN: Create request / VI: Request tạo</param>
    /// <returns>EN: Created sample ID / VI: ID sample đã tạo</returns>
    [HttpPost]
    [ProducesResponseType(typeof(CreateSampleCommandResult), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> CreateSample([FromBody] CreateSampleRequest request)
    {
        var command = new CreateSampleCommand(request.Name, request.Description);
        var result = await _mediator.Send(command);

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

    /// <summary>
    /// EN: Update an existing sample.
    /// VI: Cập nhật một sample đã tồn tại.
    /// </summary>
    /// <param name="id">EN: Sample ID / VI: ID sample</param>
    /// <param name="request">EN: Update request / VI: Request cập nhật</param>
    /// <returns>EN: Success status / VI: Trạng thái thành công</returns>
    [HttpPut("{id:guid}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> UpdateSample(Guid id, [FromBody] UpdateSampleRequest request)
    {
        var command = new UpdateSampleCommand(id, request.Name, request.Description);
        var result = await _mediator.Send(command);

        if (!result)
        {
            return NotFound(new
            {
                success = false,
                error = new
                {
                    code = "SAMPLE_NOT_FOUND",
                    message = $"Sample with ID {id} not found / Sample với ID {id} không tìm thấy"
                }
            });
        }

        return Ok(new { success = true, message = "Sample updated successfully / Sample đã cập nhật thành công" });
    }

    /// <summary>
    /// EN: Delete a sample.
    /// VI: Xóa một sample.
    /// </summary>
    /// <param name="id">EN: Sample ID / VI: ID sample</param>
    /// <returns>EN: Success status / VI: Trạng thái thành công</returns>
    [HttpDelete("{id:guid}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DeleteSample(Guid id)
    {
        var command = new DeleteSampleCommand(id);
        var result = await _mediator.Send(command);

        if (!result)
        {
            return NotFound(new
            {
                success = false,
                error = new
                {
                    code = "SAMPLE_NOT_FOUND",
                    message = $"Sample with ID {id} not found / Sample với ID {id} không tìm thấy"
                }
            });
        }

        return NoContent();
    }

    /// <summary>
    /// EN: Change sample status.
    /// VI: Thay đổi trạng thái sample.
    /// </summary>
    /// <param name="id">EN: Sample ID / VI: ID sample</param>
    /// <param name="request">EN: Status change request / VI: Request thay đổi trạng thái</param>
    /// <returns>EN: Success status / VI: Trạng thái thành công</returns>
    [HttpPatch("{id:guid}/status")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> ChangeSampleStatus(Guid id, [FromBody] ChangeStatusRequest request)
    {
        var command = new ChangeSampleStatusCommand(id, request.Status);
        var result = await _mediator.Send(command);

        if (!result)
        {
            return BadRequest(new
            {
                success = false,
                error = new
                {
                    code = "STATUS_CHANGE_FAILED",
                    message = "Failed to change sample status / Thay đổi trạng thái sample thất bại"
                }
            });
        }

        return Ok(new { success = true, message = "Sample status changed successfully / Trạng thái sample đã thay đổi thành công" });
    }
}

/// <summary>
/// EN: Request model for creating a sample.
/// VI: Model request để tạo sample.
/// </summary>
public record CreateSampleRequest(string Name, string? Description);

/// <summary>
/// EN: Request model for updating a sample.
/// VI: Model request để cập nhật sample.
/// </summary>
public record UpdateSampleRequest(string Name, string? Description);

/// <summary>
/// EN: Request model for changing sample status.
/// VI: Model request để thay đổi trạng thái sample.
/// </summary>
public record ChangeStatusRequest(string Status);
