using Contracts.DTO;
using Contracts.SearchModels;
using Contracts.Services;
using Contracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Services.Support.Exceptions;

namespace Controllers.Controllers;

[ApiController]
[Route("api/[controller]")]
public class SpendingPlanController : ControllerBase
{
    private readonly ISpendingPlanService _spendingPlanService;

    public SpendingPlanController(ISpendingPlanService spendingPlanService)
    {
        _spendingPlanService = spendingPlanService;
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<SpendingPlanViewModel>> GetSpendingPlan(
        Guid id,
        [FromQuery] SpendingPlanSearch search)
    {
        try
        {
            search ??= new();
            search.Id = id;

            var plan = await _spendingPlanService.GetDetails(search);
            return Ok(plan);
        }
        catch (EntityNotFoundException ex)
        {
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }

    [HttpGet]
    public async Task<ActionResult<List<SpendingPlanViewModel>>> GetSpendingPlans()
    {
        try
        {
            var plans = await _spendingPlanService.GetList();
            return Ok(plans);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }

    [HttpGet("filter")]
    public async Task<ActionResult<List<SpendingPlanViewModel>>> GetSpendingPlans(
        [FromQuery] SpendingPlanSearch search)
    {
        try
        {
            var plans = await _spendingPlanService.GetList(search);
            return Ok(plans);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }

    [HttpPost]
    public async Task<ActionResult<SpendingPlanViewModel>> CreateSpendingPlan(
        [FromBody] SpendingPlanDto dto)
    {
        try
        {
            var plan = await _spendingPlanService.Create(dto);
            return CreatedAtAction(nameof(GetSpendingPlan), new { id = plan.Id }, plan);
        }
        catch (EntityNotFoundException ex)
        {
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }

    [HttpPatch]
    public async Task<ActionResult<SpendingPlanViewModel>> UpdateSpendingPlan(
        [FromBody] SpendingPlanDto dto)
    {
        try
        {
            var plan = await _spendingPlanService.Update(dto);
            return Ok(plan);
        }
        catch (EntityNotFoundException ex)
        {
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }

    [HttpDelete]
    public async Task<ActionResult> DeleteSpendingPlan([FromQuery] SpendingPlanSearch search)
    {
        try
        {
            var plan = await _spendingPlanService.Delete(search);
            return Ok(plan);
        }
        catch (EntityNotFoundException ex)
        {
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }
}