using IWS5.Api.Enum;
using IWS5.Core.DTO.IAdmin.Schedules;
using IWS5.Core.Models;
using IWS5.Core.Services.IAdmin;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace IWS5.AdminApi.Controllers;

[Authorize(Roles = nameof(UserGroups.PDAdminGroup))]
[Route("admin/schedules/{scheduleId:int}/[controller]")]
[ApiController]
public class TasksController(
    IScheduleTasksService scheduleTasksService,
    ILogger<TasksController> logger)
    : ControllerBase
{
    /// <summary>
    /// Returns the list of tasks for a schedule.
    /// </summary>
    [HttpGet]
    [SwaggerOperation(Summary = "List all tasks for a schedule", Description = "Returns the list of tasks for a schedule.")]
    [ProducesResponseType(typeof(CodeResponse<List<ScheduleTaskDTO>>), 200)]
    [ProducesResponseType(400)]
    public async Task<IActionResult> GetTasks([FromRoute] ScheduleRouteDTO route)
    {
        var result = await scheduleTasksService.GetTasksAsync(route.ScheduleId);

        return result.Code == IWS5.Core.Enums.ResponseCode.NotFound
            ? NotFound(result)
            : Ok(result);
    }

    /// <summary>
    /// Returns details about a single task.
    /// </summary>
    [HttpGet("{taskId:int}")]
    [SwaggerOperation(Summary = "Get task details by ID", Description = "Returns details about a single task.")]
    [ProducesResponseType(typeof(CodeResponse<ScheduleTaskDTO>), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(404)]
    public async Task<IActionResult> GetTask([FromRoute] ScheduleTaskRouteDTO route)
    {
        var result = await scheduleTasksService.GetTaskAsync(route.TaskId);

        return result.Code == IWS5.Core.Enums.ResponseCode.NotFound
            ? NotFound(result)
            : Ok(result);
    }

    /// <summary>
    /// Creates a new task for a schedule.
    /// </summary>
    [HttpPost]
    [SwaggerOperation(Summary = "Create a new task for a schedule", Description = "Creates a new task for a schedule.")]
    [ProducesResponseType(typeof(CodeResponse<ScheduleTaskDTO>), 200)]
    [ProducesResponseType(400)]
    public async Task<IActionResult> CreateTask(
        [FromRoute] ScheduleRouteDTO route,
        [FromBody] ScheduleTaskRequestDTO request)
    {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        var result = await scheduleTasksService.CreateTaskAsync(route.ScheduleId, request);

        return result.Code == IWS5.Core.Enums.ResponseCode.NotFound
            ? NotFound(result)
            : Ok(result);
    }

    /// <summary>
    /// Updates an existing schedule task.
    /// </summary>
    [HttpPut("{taskId:int}")]
    [SwaggerOperation(Summary = "Update a task", Description = "Updates an existing schedule task.")]
    [ProducesResponseType(typeof(CodeResponse<ScheduleTaskDTO>), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(404)]
    public async Task<IActionResult> UpdateTask(
        [FromRoute] ScheduleTaskRouteDTO route,
        [FromBody] ScheduleTaskRequestDTO request)
    {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        var result = await scheduleTasksService.UpdateTaskAsync(route.TaskId, request);

        return result.Code == IWS5.Core.Enums.ResponseCode.NotFound
            ? NotFound(result)
            : Ok(result);
    }

    /// <summary>
    /// Deletes a schedule task by ID.
    /// </summary>
    [HttpDelete("{taskId:int}")]
    [SwaggerOperation(Summary = "Delete a task", Description = "Deletes a schedule task by ID.")]
    [ProducesResponseType(204)]
    [ProducesResponseType(400)]
    [ProducesResponseType(404)]
    public async Task<IActionResult> DeleteTask([FromRoute] ScheduleTaskRouteDTO route)
    {
        var deleted = await scheduleTasksService.DeleteTaskAsync(route.TaskId);

        return deleted
            ? NoContent()
            : NotFound(new { message = "Task not found." });
    }

    /// <summary>
    /// Triggers a schedule task to run.
    /// </summary>
    [HttpPost("{taskId:int}/run")]
    [SwaggerOperation(Summary = "Run a task manually", Description = "Triggers a schedule task to run.")]
    [ProducesResponseType(200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(404)]
    public async Task<IActionResult> RunTask([FromRoute] ScheduleTaskRouteDTO route)
    {
        // TODO: the service result (don’t always return OK)
        var triggered = await scheduleTasksService.RunTaskAsync(route.TaskId);

        return triggered
            ? Ok(new { success = true, message = $"Task {route.TaskId} triggered successfully for Schedule {route.ScheduleId}" })
            : NotFound(new { success = false, message = $"Task {route.TaskId} not found (or cannot be triggered)." });
    }
}
