using MealPlan.Api.DTOs.MealPlan;
using MealPlan.Api.Extensions;
using MealPlan.Api.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace MealPlan.Api.Controllers;

[ApiController]
[Route("api/meal-plan")]
[Authorize]
public class MealPlanController : ControllerBase
{
    private readonly IMealPlanService _mealPlanService;

    public MealPlanController(IMealPlanService mealPlanService) => _mealPlanService = mealPlanService;

    [HttpGet]
    [ProducesResponseType(typeof(IReadOnlyList<MealPlanEntryDto>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetEntries([FromQuery] DateOnly from, [FromQuery] DateOnly to, CancellationToken ct)
    {
        if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
        var entries = await _mealPlanService.GetEntriesAsync(userId, from, to, ct);
        return Ok(entries);
    }

    [HttpPut]
    [ProducesResponseType(typeof(MealPlanEntryDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> UpsertEntry([FromBody] UpsertMealPlanEntryDto dto, CancellationToken ct)
    {
        if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
        var entry = await _mealPlanService.UpsertEntryAsync(userId, dto, ct);
        return entry is null ? NotFound(new { error = "Recipe not found." }) : Ok(entry);
    }

    [HttpDelete("{id:int}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DeleteEntry(int id, CancellationToken ct)
    {
        if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
        var deleted = await _mealPlanService.DeleteEntryAsync(userId, id, ct);
        return deleted ? NoContent() : NotFound();
    }

    [HttpGet("shopping-list")]
    [ProducesResponseType(typeof(IReadOnlyList<ShoppingListItemDto>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetShoppingList([FromQuery] DateOnly from, [FromQuery] DateOnly to, CancellationToken ct)
    {
        if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
        var items = await _mealPlanService.GetShoppingListAsync(userId, from, to, ct);
        return Ok(items);
    }
}
