using System.Globalization;
using ApiDenuncias.Services;
using GestionaDenuncias.Shared.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace ApiDenuncias.Controllers;

[ApiController]
[Authorize]
[Route("api/configuration")]
public sealed class ConfigurationController : ControllerBase
{
    private readonly AppConfigurationService _configurationService;
    private readonly WorkGroupAdministrationService _workGroupService;

    public ConfigurationController(
        AppConfigurationService configurationService,
        WorkGroupAdministrationService workGroupService)
    {
        _configurationService = configurationService;
        _workGroupService = workGroupService;
    }

    [HttpGet]
    public async Task<ActionResult<AppConfigurationDto>> Get(CancellationToken cancellationToken)
    {
        return Ok(await _configurationService.GetAsync(cancellationToken));
    }

    [HttpPut("external-update-cutoff")]
    [Authorize(Policy = "ConfigurationAdministrators")]
    public async Task<ActionResult<AppConfigurationDto>> SetExternalUpdateCutoff(
        UpdateExternalUpdateCutoffRequest request,
        CancellationToken cancellationToken)
    {
        DateOnly? date = null;
        if (!string.IsNullOrWhiteSpace(request.Date))
        {
            if (!DateOnly.TryParseExact(
                request.Date.Trim(),
                ["yyyy-MM-dd", "dd/MM/yyyy"],
                CultureInfo.InvariantCulture,
                DateTimeStyles.None,
                out var parsed))
            {
                return BadRequest(new ApiError("Debes indicar una fecha valida con formato YYYY-MM-DD o DD/MM/AAAA."));
            }

            date = parsed;
        }

        return Ok(await _configurationService.SetExternalUpdateCutoffDateAsync(date, cancellationToken));
    }

    [HttpGet("work-groups")]
    [Authorize(Policy = "ConfigurationAdministrators")]
    public async Task<ActionResult<WorkGroupAdministrationDto>> GetWorkGroups(
        CancellationToken cancellationToken)
    {
        return Ok(await _workGroupService.GetAsync(cancellationToken));
    }

    [HttpGet("work-groups/current")]
    public async Task<ActionResult<CurrentUserWorkGroupsDto>> GetCurrentUserWorkGroups(
        CancellationToken cancellationToken)
    {
        var username = User.Identity?.Name ??
                       throw new InvalidOperationException("No hay usuario autenticado.");

        return Ok(await _workGroupService.GetUserGroupsAsync(username, cancellationToken));
    }

    [HttpPut("work-groups/users/{username}")]
    [Authorize(Policy = "ConfigurationAdministrators")]
    public async Task<ActionResult<WorkGroupAdministrationDto>> SetUserWorkGroups(
        string username,
        UpdateUserWorkGroupsRequest request,
        CancellationToken cancellationToken)
    {
        var changedBy = User.Identity?.Name ??
                        throw new InvalidOperationException("No hay usuario autenticado.");

        try
        {
            return Ok(await _workGroupService.UpdateUserGroupsAsync(
                username,
                request.GroupCodes ?? [],
                changedBy,
                cancellationToken));
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new ApiError(ex.Message));
        }
    }
}
