using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using Microsoft.AspNetCore.Mvc;

namespace DigitalData.Core.API
{
    /// <summary>
    /// A base controller class providing  Read operation for a specified entity type,
    /// with enhanced error handling to ensure robust and reliable API endpoints.
    /// </summary>
    /// <typeparam name="TReadDto">The Data Transfer Object type for read operations.</typeparam>
    /// <typeparam name="TEntity">The entity type CRUD operations will be performed on.</typeparam>
    /// <typeparam name="TId">The type of the entity's identifier.</typeparam>
    [ApiController]
    [Route("api/[controller]")]
    [Obsolete("Use MediatR")]
    public class ReadControllerBaseWithErrorHandling<TReadService, TReadDto, TEntity, TId> : ControllerBase
        where TReadService : IReadService<TReadDto, TEntity, TId>
        where TReadDto : class
        where TEntity : class
    {
        protected readonly ILogger _logger;
        protected readonly TReadService _service;

        /// <summary>
        /// Initializes a new instance of the CRUDControllerBase class with specified logger and CRUD service.
        /// </summary>
        /// <param name="logger">The logger to be used by the controller.</param>
        /// <param name="service">The CRUD service handling business logic for the entity.</param>
        public ReadControllerBaseWithErrorHandling(
            ILogger logger,
            TReadService service)
        {
            _logger = logger;
            _service = service;
        }

        /// <summary>
        /// Retrieves an entity by its identifier.
        /// </summary>
        /// <param name="id">The identifier of the entity to retrieve.</param>
        /// <returns>A task that represents the asynchronous read operation. The task result contains the action result.</returns>
        [HttpGet("{id}")]
        public virtual async Task<IActionResult> GetById([FromRoute] TId id)
        {
            try
            {
                return await _service.ReadByIdAsync(id).ThenAsync(
                    Success: Ok,
                    Fail: IActionResult (messages, notices) =>
                    {
                        _logger.LogNotice(notices);
                        return NotFound(messages);
                    });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "{Message}", ex.Message);
                return StatusCode(StatusCodes.Status500InternalServerError);
            }
        }

        /// <summary>
        /// Retrieves all entities.
        /// </summary>
        /// <returns>A task that represents the asynchronous read-all operation. The task result contains the action result.</returns>
        [HttpGet]
        public virtual async Task<IActionResult> GetAll()
        {
            try
            {
                return await _service.ReadAllAsync().ThenAsync(
                    Success: Ok,
                    Fail: IActionResult (messages, notices) =>
                    {
                        _logger.LogNotice(notices);
                        return NotFound(messages);
                    });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "{Message}", ex.Message);
                return StatusCode(StatusCodes.Status500InternalServerError);
            }
        }
    }
}