using Hl7.Fhir.Model;
using Hl7.Fhir.Serialization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using static Hl7.Fhir.Model.CapabilityStatement;

/// <summary>
/// FHIR R4 CapabilityStatement metadata for the inbound facade.
/// </summary>
[ApiController]
[Route("fhir/R4")]
[ServiceFilter(typeof(FhirExceptionFilter))]
public class FhirMetadataController : ControllerBase
{
    /// <summary>
    /// Returns the FHIR R4 CapabilityStatement describing supported interactions.
    /// </summary>
    /// <returns>CapabilityStatement in application/fhir+json.</returns>
    [HttpGet("metadata")]
    [AllowAnonymous]
    [Produces("application/fhir+json")]
    [ProducesResponseType(typeof(CapabilityStatement), StatusCodes.Status200OK)]
    public IActionResult Metadata()
    {
        var capability = new CapabilityStatement
        {
            Status = PublicationStatus.Active,
            Date = DateTimeOffset.UtcNow.ToString("o"),
            Kind = CapabilityStatementKind.Instance,
            Software = new CapabilityStatement.SoftwareComponent { Name = "VigilCare Clinical" },
            Implementation = new CapabilityStatement.ImplementationComponent
            {
                Description = "VigilCare Clinical FHIR R4 facade",
                Url = $"{Request.Scheme}://{Request.Host}/fhir/R4"
            },
            FhirVersion = FHIRVersion.N4_0_1,
            Format = new[] { "application/fhir+json" },
            Rest = new List<CapabilityStatement.RestComponent>
            {
                new()
                {
                    Mode = CapabilityStatement.RestfulCapabilityMode.Server,
                    Resource = new List<CapabilityStatement.ResourceComponent>
                    {
                        ResourceCapability("Patient",
                            TypeRestfulInteraction.Create,
                            TypeRestfulInteraction.Read,
                            TypeRestfulInteraction.SearchType),
                        ResourceCapability("Encounter",
                            TypeRestfulInteraction.Create,
                            TypeRestfulInteraction.Read,
                            TypeRestfulInteraction.SearchType),
                        ResourceCapability("Observation", TypeRestfulInteraction.Create),
                        ResourceCapability("MedicationAdministration", TypeRestfulInteraction.Create),
                        new CapabilityStatement.ResourceComponent
                        {
                            Type = "Bundle",
                            Interaction = new List<CapabilityStatement.ResourceInteractionComponent>
                            {
                                new() { Code = TypeRestfulInteraction.Create }
                            }
                        }
                    }
                }
            }
        };

        return Content(new FhirJsonSerializer().SerializeToString(capability), "application/fhir+json");
    }

    private static CapabilityStatement.ResourceComponent ResourceCapability(
        string type, params TypeRestfulInteraction[] interactions) =>
        new()
        {
            Type = type,
            Interaction = interactions
                .Select(i => new CapabilityStatement.ResourceInteractionComponent { Code = i })
                .ToList()
        };
}