using Hl7.Fhir.Model;
using FhirEncounter = Hl7.Fhir.Model.Encounter;

public static class EncounterMapper
{
    /// <summary>
    /// Maps a VigilCare Encounter entity to a FHIR R4 Encounter resource.
    ///
    /// Mapping decisions:
    /// - VigilCare encounter Status ("active", "discharged") maps to FHIR
    ///   Encounter.Status (in-progress, finished).
    /// - Department maps to Encounter.serviceType using a local CodeSystem.
    ///   Facilities should map to their own department OID or SNOMED CT codes.
    /// - SourceBatchId is preserved as an extension for traceability.
    /// </summary>
    public static FhirEncounter ToFhir(Encounter entity, string baseUrl)
    {
        var encounter = new FhirEncounter
        {
            Id = entity.Id.ToString(),
            Meta = new Meta
            {
                VersionId = "1",
                LastUpdated = entity.UpdatedAt,
            },
            Status = entity.Status?.ToLowerInvariant() switch
            {
                "active" => FhirEncounter.EncounterStatus.InProgress,
                "discharged" => FhirEncounter.EncounterStatus.Finished,
                "cancelled" => FhirEncounter.EncounterStatus.Cancelled,
                _ => FhirEncounter.EncounterStatus.Unknown,
            },
            Class = new Coding(
                "http://terminology.hl7.org/CodeSystem/v3-ActCode",
                "IMP",
                "inpatient encounter"),
            Subject = new ResourceReference($"Patient/{entity.PatientId}"),
        };

        if (entity.AdmissionDate.HasValue)
        {
            encounter.Period = new Period
            {
                StartElement = new FhirDateTime(entity.AdmissionDate.Value),
            };
        }

        if (entity.Department.HasValue)
        {
            encounter.ServiceType = new CodeableConcept(
                "urn:vigilcare:department",
                entity.Department.Value.ToString(),
                entity.Department.Value.ToString());
        }

        if (!string.IsNullOrEmpty(entity.RoomBed))
        {
            encounter.Location.Add(new FhirEncounter.LocationComponent
            {
                Location = new ResourceReference { Display = entity.RoomBed },
                Status = FhirEncounter.EncounterLocationStatus.Active,
            });
        }

        if (!string.IsNullOrEmpty(entity.AdmissionReason))
        {
            encounter.ReasonCode.Add(new CodeableConcept { Text = entity.AdmissionReason });
        }

        if (!string.IsNullOrEmpty(entity.DischargeDiagnosis))
        {
            encounter.Diagnosis.Add(new FhirEncounter.DiagnosisComponent
            {
                Condition = new ResourceReference { Display = entity.DischargeDiagnosis },
                Use = new CodeableConcept(
                    "http://terminology.hl7.org/CodeSystem/diagnosis-role",
                    "DD", "Discharge diagnosis"),
            });
        }

        if (entity.SourceBatchId.HasValue)
        {
            encounter.Extension.Add(new Extension(
                "urn:vigilcare:source-batch-id",
                new FhirString(entity.SourceBatchId.Value.ToString())));
        }

        return encounter;
    }
}
