using adas_core.Domain.Models.MongoModels;
using MongoDB.Bson;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace adas_core.Domain.Models;

public class BasePatientObservation : JsonConverter
{
    public ObjectId Id { get; set; }
    public ObjectId PatientId { get; set; }
    public ObjectId? UserId { get; set; }

    public string? ClinicalEpisode { get; set; }

    public Patient? Patient { get; set; }

    public string? SystemId { get; set; }


    public string? Code { get; set; }


    public string? CodingSystem { get; set; }

    public ParentDataClass? ParentData { get; set; }


    public DateTime Time { get; set; }
    public DateTime? EndTime { get; set; }


    public string? Name { get; set; }


    public string? Units { get; set; }

    public bool CheckObservations { get; set; }

    public List<ConfigObservation>? CreateObservation { get; set; }

    public string? ToJsonString()
    {
        try
        {
            return JsonConvert.SerializeObject(this, Formatting.None);
        }
        catch
        {
            return base.ToString();
        }
    }

    public override string ToString()
    {
        List<string> items =
        [
            $"id: {Id}",
            $"patientid: {PatientId}"
        ];
        if (!string.IsNullOrEmpty(SystemId)) items.Add($", systemId: {SystemId}");
        if (!string.IsNullOrEmpty(Code)) items.Add($"code: {Code}");
        if (!string.IsNullOrEmpty(CodingSystem)) items.Add($"codingSystem: {CodingSystem}");
        items.Add($"time: {Time}");
        if (EndTime.HasValue) items.Add($"endTime: {EndTime.Value}");
        if (!string.IsNullOrEmpty(Name)) items.Add($"name: {Name}");
        if (!string.IsNullOrEmpty(Units)) items.Add($"unit: {Units}");
        items.Add($"checkObservations: {CheckObservations}");
        CreateObservation?.ForEach(o => items.Add(o.ToString()));

        return "BasePatientObservation[" + string.Join(", ", items) + "]";
    }

    public List<string> ToListString()
    {
        List<string> items =
        [
            $"id: {Id}",
            $"patientid: {PatientId}"
        ];
        if (!string.IsNullOrEmpty(SystemId)) items.Add($"systemId: {SystemId}");
        if (!string.IsNullOrEmpty(Code)) items.Add($"code: {Code}");
        if (!string.IsNullOrEmpty(CodingSystem)) items.Add($"codingSystem: {CodingSystem}");
        items.Add($"time: {Time}");
        if (!string.IsNullOrEmpty(Name)) items.Add($"name: {Name}");
        return items;
    }


    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(BasePatientObservation);
    }

    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        if (value == null) return;

        var jo = JObject.FromObject(value);
        jo.Property("Id")?.Remove();
        jo.Property("Patient")?.Remove();
        jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object? existingValue,
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

public class ParentDataClass
{
    public string? Code { get; set; }

    public string? CodingSystem { get; set; }

    public string? Name { get; set; }
}