Clear        


                
                    using Locations.APP.Features.Locations;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace Locations.API.Controllers
{
    /// <summary>
    /// API controller for handling location-related operations.
    /// Provides endpoints for querying and joining country and city data.
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class LocationsController : ControllerBase
    {
        /// <summary>
        /// The mediator instance used to send requests to the appropriate handlers.
        /// </summary>
        private readonly IMediator _mediator;

        /// <summary>
        /// Initializes a new instance of the <see cref="LocationsController"/> class.
        /// </summary>
        /// <param name="mediator">The mediator used for sending requests to handlers.</param>
        public LocationsController(IMediator mediator)
        {
            _mediator = mediator;
        }

        /// <summary>
        /// Executes an inner join query between countries and cities, with support for filtering, ordering, and paging.
        /// The route of the action is api/Locations/InnerJoin.
        /// </summary>
        /// <param name="request">
        /// The <see cref="LocationInnerJoinQueryRequest"/> containing filter, order, and paging parameters.
        /// </param>
        /// <returns>
        /// An <see cref="IActionResult"/> containing a list of joined country-city records if found; otherwise, returns NoContent.
        /// </returns>
        /// <remarks>
        /// This endpoint accepts a POST request with a body containing the query parameters.
        /// It delegates the query to the MediatR pipeline, which is handled by <see cref="LocationInnerJoinQueryHandler"/>.
        /// The handler performs the join, applies filters, ordering, and paging, and returns the result as a queryable.
        /// The result is materialized to a list asynchronously. If the list contains any records, an HTTP 200 OK response is returned with the data.
        /// If no records are found, an HTTP 204 No Content response is returned.
        /// </remarks>
        [HttpPost("[action]")]
        public async Task<IActionResult> InnerJoin(LocationInnerJoinQueryRequest request)
        {
            // Send the request to the MediatR pipeline, which will be handled by the appropriate handler.
            var response = await _mediator.Send(request);

            // Materialize the queryable result to a list asynchronously.
            var list = await response.ToListAsync();

            // If the result contains any records, return them with HTTP 200 OK.
            if (list.Any())
                return Ok(list);

            // If no records are found, return HTTP 204 No Content.
            return NoContent();
        }

        /// <summary>
        /// Executes a left join query between countries and cities, with support for filtering, ordering, and paging.
        /// The route of the action is api/Locations/LeftJoin.
        /// </summary>
        /// <param name="request">
        /// The <see cref="LocationLeftJoinQueryRequest"/> containing filter, order, and paging parameters.
        /// </param>
        /// <returns>
        /// An <see cref="IActionResult"/> containing a list of joined country-city records if found; otherwise, returns NoContent.
        /// </returns>
        /// <remarks>
        /// This endpoint accepts a POST request with a body containing the query parameters.
        /// It delegates the query to the MediatR pipeline, which is handled by <see cref="LocationLeftJoinQueryHandler"/>.
        /// The handler performs the join, applies filters, ordering, and paging, and returns the result as a queryable.
        /// The result is materialized to a list asynchronously. If the list contains any records, an HTTP 200 OK response is returned with the data.
        /// If no records are found, an HTTP 204 No Content response is returned.
        /// </remarks>
        [HttpPost("[action]")]
        public async Task<IActionResult> LeftJoin(LocationLeftJoinQueryRequest request)
        {
            // Send the request to the MediatR pipeline, which will be handled by the appropriate handler.
            var response = await _mediator.Send(request);

            // Materialize the queryable result to a list asynchronously.
            var list = await response.ToListAsync();

            // If the result contains any records, return them with HTTP 200 OK.
            if (list.Any())
                return Ok(list);

            // If no records are found, return HTTP 204 No Content.
            return NoContent();
        }
    }
}