using Hl7.Fhir.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("fhir/Patient")]
[Produces("application/fhir+json")]
[Authorize]
public class FhirPatientController : ControllerBase
{
    private readonly IFhirService _fhir;

    public FhirPatientController(IFhirService fhir) => _fhir = fhir;

    /// <summary>
    /// FHIR read: GET /fhir/Patient/{id}
    /// Returns a single Patient resource by logical ID.
    /// </summary>
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(Hl7.Fhir.Model.Patient), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(Hl7.Fhir.Model.OperationOutcome), StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Read(string id)
    {
        var patient = await _fhir.GetPatientAsync(Guid.Parse(id));
        if (patient is null)
            return NotFound(FhirErrorHelper.NotFound("Patient", id));

        return Ok(patient);
    }

    /// <summary>
    /// FHIR search: GET /fhir/Patient?name=X&amp;birthdate=Y&amp;identifier=Z
    /// Supports search by name (contains), birthdate (exact), and MRN identifier.
    /// Returns a FHIR Bundle of type searchset.
    /// </summary>
    [HttpGet]
    [ProducesResponseType(typeof(Hl7.Fhir.Model.Bundle), StatusCodes.Status200OK)]
    public async Task<IActionResult> Search(
        [FromQuery] string? name,
        [FromQuery] string? birthdate,
        [FromQuery] string? identifier,
        [FromQuery(Name = "_count")] int count = 20,
        [FromQuery(Name = "_offset")] int offset = 0)
    {
        var bundle = await _fhir.SearchPatientsAsync(name, birthdate, identifier, count, offset);
        return Ok(bundle);
    }

    /// <summary>
    /// FHIR $everything: GET /fhir/Patient/{id}/$everything
    /// Returns a Bundle containing the Patient resource, all Encounters,
    /// and all Observations for the patient.
    /// </summary>
    [HttpGet("{id}/$everything")]
    [ProducesResponseType(typeof(Bundle), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(OperationOutcome), StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Everything(string id)
    {
        var bundle = await _fhir.GetPatientEverythingAsync(Guid.Parse(id));
        if (bundle is null)
            return NotFound(FhirErrorHelper.NotFound("Patient", id));

        return Ok(bundle);
    }    
}