//extern alias stu3;
//extern alias r4;

//using STU3Model = stu3::Hl7.Fhir.Model;
//using STU3Rest = stu3::Hl7.Fhir.Rest;

//using R4Model = r4::Hl7.Fhir.Model;
//using R4Rest = r4::Hl7.Fhir.Rest;

using Compare.Models;
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Hl7.Fhir.Serialization;
using Task = System.Threading.Tasks.Task;

namespace Compare.Client;

internal class FhirSession
{
    public bool IsAvailable { get; set; }
    public string ErrorMessage { get; set; } = string.Empty;

    public Server Server { get; set; } = new();
    public FhirClient? Client { get; set; }
    public CapabilityStatement? Metadata { get; set; }

    // TODO: Let's move this away if we're using this more. For now a quick way of keeping some results for comparisation.
    public Bundle? TestResults1 { get; set; } // FhirQuery.Test1_PatientEverything
    public Bundle? TestResults2 { get; set; } // FhirQuery.Test2_PatientEverythingWithPagination
    public Bundle? TestResults3 { get; set; } // FhirQuery.Test3_PatientIdEverything
    public Bundle? TestResults4 { get; set; } // FhirQuery.Test4_PatientIdEverythingWithPagination
    public Bundle? TestResults5 { get; set; } // FhirQuery.Test5_PatientExport
    public Bundle? TestResults6 { get; set; } // FhirQuery.Test6_PatientIdExport
    public Bundle? TestResults7 { get; set; } // FhirQuery.Test7_PatientDocument
    public Bundle? TestResults8 { get; set; } // FhirQuery.Test8_PatientIdDocument
    public Bundle? TestResults9 { get; set; } // FhirQuery.Test9_PatientIdEverythingWithInclude
    public Bundle? TestResults10 { get; set; } // FhirQuery.Test10_PatientIdEverythingWithIncludes
    public Bundle? TestResults11 { get; set; } // FhirQuery.Test11_PatientIdEverythingWithIncludeWildcard
    public Bundle? TestResults12 { get; set; } // FhirQuery.Test12_PatientIdEverythingWithType


    public static async Task<FhirSession> CreateSession(Server server)
    {
        var settings = new FhirClientSettings
        {
            Timeout = 30_000,
            VerifyFhirVersion = false,
            PreferredFormat = ResourceFormat.Json,
            ReturnPreference = ReturnPreference.Representation,
        };

        try
        {
            if (!server.Enabled) throw new Exception("Disabled in config.");

            var client = new FhirClient(server.BaseUrl, settings);
            var metadata = await client.CapabilityStatementAsync();
            return new FhirSession()
            {
                IsAvailable = true,
                Server = server,
                Client = client,
                Metadata = metadata
            };
        }
        catch (Exception ex)
        {
            return new FhirSession()
            {
                IsAvailable = false,
                ErrorMessage = ex.Message,
                Server = server,
            };
        }
    }

    public async Task Import(FhirSession session, string fileName)
    {
        var contents = File.ReadAllText(fileName).Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "");
        var parser = new FhirXmlParser();
        var resource = parser.Parse<Resource>(contents);
        // var resourceTypeName = XElement.Parse(contents).Name.LocalName;
        // Console.WriteLine($" - {Path.GetFileName(fileName)} -> {resource.TypeName} ({resource.Id}) ");

        try
        {
            
            await session.Client?.UpdateAsync(resource);
        }
        catch (Exception e)
        {
            Console.WriteLine($" - Error {Path.GetFileName(fileName)}: {e.Message}");
        }
    }

}
