// EN: Handler for GetOrdersByCustomerQuery using Dapper.
// VI: Handler cho GetOrdersByCustomerQuery dùng Dapper.

using System.Data;
using Dapper;
using MediatR;
using OrderService.API.Application.DTOs;

namespace OrderService.API.Application.Queries;

/// <summary>
/// EN: Handler for getting customer orders using Dapper.
/// VI: Handler lấy orders của khách hàng dùng Dapper.
/// </summary>
public class GetOrdersByCustomerQueryHandler : IRequestHandler<GetOrdersByCustomerQuery, PagedResult<OrderSummaryDto>>
{
    private readonly IDbConnection _connection;
    private readonly ILogger<GetOrdersByCustomerQueryHandler> _logger;

    public GetOrdersByCustomerQueryHandler(
        IDbConnection connection,
        ILogger<GetOrdersByCustomerQueryHandler> logger)
    {
        _connection = connection ?? throw new ArgumentNullException(nameof(connection));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<PagedResult<OrderSummaryDto>> Handle(
        GetOrdersByCustomerQuery request,
        CancellationToken cancellationToken)
    {
        // EN: Get total count
        // VI: Lấy tổng số
        const string countSql = "SELECT COUNT(*) FROM orders WHERE customer_id = @CustomerId";
        var totalCount = await _connection.ExecuteScalarAsync<int>(countSql, new { request.CustomerId }, commandTimeout: 5);

        // EN: Get paged data
        // VI: Lấy dữ liệu phân trang
        const string sql = @"
            SELECT 
                o.id AS Id,
                o.shop_id AS ShopId,
                o.customer_id AS CustomerId,
                os.name AS Status,
                o.total_amount AS TotalAmount,
                o.created_at AS CreatedAt,
                (SELECT COUNT(*) FROM order_items WHERE order_id = o.id) AS ItemCount
            FROM orders o
            INNER JOIN order_statuses os ON o.status_id = os.id
            WHERE o.customer_id = @CustomerId
            ORDER BY o.created_at DESC
            LIMIT @PageSize OFFSET @Offset";

        var parameters = new
        {
            request.CustomerId,
            request.PageSize,
            Offset = (request.Page - 1) * request.PageSize
        };

        var orders = await _connection.QueryAsync<OrderSummaryDto>(sql, parameters, commandTimeout: 5);

        return new PagedResult<OrderSummaryDto>(
            orders.ToList(),
            totalCount,
            request.PageSize,
            request.Page
        );
    }
}
