using adas_core.Application.Exceptions;
using adas_core.Application.Services.Interfaces;
using adas_core.Authentication.Attributes;
using adas_core.Domain.Enums;
using adas_core.Domain.Models.GroupedObservations;
using adas_core.Logging;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;

namespace adas_core.Controllers;

[Route("grouped-observations")]
[ApiController]
public class GroupedObservationsController : ControllerBase
{
    private readonly IGroupedObservationService _groupedObservationService;

    public GroupedObservationsController(IGroupedObservationService groupedObservationService)
    {
        LogExecutionContext.TrySetTraceIdentifier(Guid.NewGuid().ToString(), true);

        _groupedObservationService = groupedObservationService;
    }


    /// <summary>
    /// Generates a grouped observation for the specified source identifier based on the provided grouping configuration.
    /// Validates that the supplied identifier is a valid ObjectId before delegating to the grouped observation service.
    /// </summary>
    /// <param name="id">The string identifier of the source for which the grouped observation is generated; must be a valid ObjectId.</param>
    /// <param name="groupedConfig">The configuration that defines how observations should be grouped.</param>
    /// <returns>An <see cref="IActionResult"/> containing the generated grouped observation wrapped in an HTTP 200 OK response.</returns>
    /// <exception cref="BadRequestException">Thrown when <paramref name="id"/> is null, empty, or not in a valid ObjectId format.</exception>
    [HttpPost]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    [PermissionAuthorize("Source", "DisplayId")]
    public async Task<IActionResult> GetGroupedObservationAsync(string id, GroupedField groupedConfig)
    {
        if (string.IsNullOrEmpty(id) || !ObjectId.TryParse(id, out var objectId))
            throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
        var groupedObs = await _groupedObservationService.GenerateGroupedObservation(objectId, groupedConfig);
        return Ok(groupedObs);
    }
}