using Adaptation.Shared;
using Adaptation.Shared.Methods;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;

namespace Adaptation.FileHandlers.jpeg;

public class Description : IDescription
{

    public int Test { get; set; }
    public int Count { get; set; }
    public int Index { get; set; }
    //
    public string EventName { get; set; }
    public string NullData { get; set; }
    public string JobID { get; set; }
    public string Sequence { get; set; }
    public string MesEntity { get; set; }
    public string ReportFullPath { get; set; }
    public string ProcessJobID { get; set; }
    public string MID { get; set; }
    //
    public string Process { get; set; } //5
    public string Date { get; set; } //6
    public string Part { get; set; } //7
    public string Lot { get; set; } //8

    string IDescription.GetEventDescription() => "File Has been read and parsed";

    List<string> IDescription.GetNames(IFileRead fileRead, Logistics logistics)
    {
        List<string> results = new();
        IDescription description = GetDefault(fileRead, logistics);
        string json = JsonSerializer.Serialize(description, description.GetType());
        object @object = JsonSerializer.Deserialize<object>(json);
        if (@object is not JsonElement jsonElement)
            throw new Exception();
        foreach (JsonProperty jsonProperty in jsonElement.EnumerateObject())
            results.Add(jsonProperty.Name);
        return results;
    }

    List<string> IDescription.GetDetailNames()
    {
        List<string> results = new();
        return results;
    }

    List<string> IDescription.GetHeaderNames()
    {
        string[] results = new string[] { nameof(Process), nameof(Date), nameof(Part), nameof(Lot) };
        return results.ToList();
    }

    IDescription IDescription.GetDisplayNames()
    {
        Description result = GetDisplayNames();
        return result;
    }

    List<string> IDescription.GetParameterNames()
    {
        List<string> results = new();
        return results;
    }

    JsonProperty[] IDescription.GetDefault(IFileRead fileRead, Logistics logistics)
    {
        JsonProperty[] results;
        IDescription description = GetDefault(fileRead, logistics);
        string json = JsonSerializer.Serialize(description, description.GetType());
        object @object = JsonSerializer.Deserialize<object>(json);
        results = ((JsonElement)@object).EnumerateObject().ToArray();
        return results;
    }

    List<string> IDescription.GetPairedParameterNames()
    {
        string[] results = new string[] { "Test Name", "Test Value" };
        return results.ToList();
    }

    List<string> IDescription.GetIgnoreParameterNames(Test test)
    {
        List<string> results = new();
        return results;
    }

    IDescription IDescription.GetDefaultDescription(IFileRead fileRead, Logistics logistics)
    {
        Description result = GetDefault(fileRead, logistics);
        return result;
    }

    Dictionary<string, string> IDescription.GetDisplayNamesJsonElement(IFileRead fileRead)
    {
        Dictionary<string, string> results = new();
        IDescription description = GetDisplayNames();
        string json = JsonSerializer.Serialize(description, description.GetType());
        JsonElement jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
        foreach (JsonProperty jsonProperty in jsonElement.EnumerateObject())
        {
            if (!results.ContainsKey(jsonProperty.Name))
                results.Add(jsonProperty.Name, string.Empty);
            if (jsonProperty.Value is JsonElement jsonPropertyValue)
                results[jsonProperty.Name] = jsonPropertyValue.ToString();
        }
        return results;
    }

    List<IDescription> IDescription.GetDescriptions(IFileRead fileRead, Logistics logistics, List<Test> tests, IProcessData iProcessData)
    {
        List<IDescription> results = new();

        if (iProcessData is null || !iProcessData.Details.Any() || iProcessData is not ProcessData)
            results.Add(GetDefault(fileRead, logistics));
        else
        {
            string nullData;
            Description description;
            object configDataNullData = fileRead.NullData;
            if (configDataNullData is null)
                nullData = string.Empty;
            else
                nullData = configDataNullData.ToString();
            for (int i = 0; i < iProcessData.Details.Count; i++)
            {
                if (iProcessData.Details[i] is not string detail)
                    continue;
                description = new Description
                {
                    Test = (int)tests[i],
                    Count = tests.Count,
                    Index = i,
                    //
                    EventName = fileRead.EventName,
                    NullData = nullData,
                    JobID = fileRead.CellInstanceName,
                    Sequence = logistics.Sequence.ToString(),
                    MesEntity = logistics.MesEntity,
                    ReportFullPath = logistics.ReportFullPath,
                    ProcessJobID = logistics.ProcessJobID,
                    MID = logistics.MID,
                    //
                    Process = logistics.ProcessJobID,
                    Date = logistics.DateTimeFromSequence.Ticks.ToString(),
                    Part = string.Empty,
                    Lot = detail
                };
                results.Add(description);
            }
        }
        return results;
    }

    private static Description GetDisplayNames()
    {
        Description result = new();
        return result;
    }

    private Description GetDefault(IFileRead fileRead, Logistics logistics)
    {
        Description result = new()
        {
            Test = -1,
            Count = 0,
            Index = -1,
            //
            EventName = fileRead.EventName,
            NullData = fileRead.NullData,
            JobID = fileRead.CellInstanceName,
            Sequence = logistics.Sequence.ToString(),
            MesEntity = fileRead.MesEntity,
            ReportFullPath = logistics.ReportFullPath,
            ProcessJobID = logistics.ProcessJobID,
            MID = logistics.MID
        };
        result.Process = nameof(Process);
        result.Date = nameof(Date);
        result.Part = nameof(Part);
        result.Lot = nameof(Lot);
        return result;
    }

}