namespace View_by_Distance.Shared.Models.Stateless;

internal abstract class XResult
{

    internal static string GetResultsDateGroupDirectory(ResultConfiguration resultConfiguration, string description, string jsonGroup)
    {
        string result = Path.Combine(GetResultsDateGroupDirectory(resultConfiguration, description), jsonGroup);
        if (!Directory.Exists(result))
            _ = Directory.CreateDirectory(result);
        return result;
    }

    internal static string GetResultsDateGroupDirectory(ResultConfiguration resultConfiguration, string description)
    {
        string result = Path.Combine(GetResultsGroupDirectory(resultConfiguration, description, create: true), resultConfiguration.DateGroup);
        if (!Directory.Exists(result))
            _ = Directory.CreateDirectory(result);
        return result;
    }

    internal static string GetRelativePath(ResultConfiguration resultConfiguration, string path)
    {
        string result = Methods.IPath.GetRelativePath(path, resultConfiguration.RootDirectory.Length);
        return result;
    }

    private static void VerifyDirectories(ResultConfiguration resultConfiguration, string dateGroupDirectory, string jsonGroup)
    {
        string checkDirectory;
        int currentYear = DateTime.Now.Year;
        for (int i = resultConfiguration.EpicYear; i < currentYear + 1; i++)
        {
            checkDirectory = Path.Combine(dateGroupDirectory, jsonGroup, i.ToString());
            if (!Directory.Exists(checkDirectory))
                _ = Directory.CreateDirectory(checkDirectory);
        }
    }

    private static void CheckContent(ResultConfiguration resultConfiguration, string dateGroupDirectory, string contentDescription, string result)
    {
        VerifyDirectories(resultConfiguration, dateGroupDirectory, resultConfiguration.ResultContent);
        string contentDirectory = new(result.Replace("<>", resultConfiguration.ResultContent));
        if (!Directory.Exists(contentDirectory))
            _ = Directory.CreateDirectory(contentDirectory);
        string checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription));
        if (!Directory.Exists(checkDirectory))
            _ = Directory.CreateDirectory(checkDirectory);
    }

    private static void CheckSingleton(ResultConfiguration resultConfiguration, string dateGroupDirectory, string singletonDescription, bool converted, string result)
    {
        VerifyDirectories(resultConfiguration, dateGroupDirectory, resultConfiguration.ResultSingleton);
        if (!converted)
        {
            string singletonDirectory = new(result.Replace("<>", resultConfiguration.ResultSingleton));
            if (!Directory.Exists(singletonDirectory))
                _ = Directory.CreateDirectory(singletonDirectory);
        }
        string checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription));
        if (!Directory.Exists(checkDirectory))
            _ = Directory.CreateDirectory(checkDirectory);
    }

    private static void CheckCollection(ResultConfiguration resultConfiguration, string dateGroupDirectory, string collectionDescription, bool converted, string result)
    {
        VerifyDirectories(resultConfiguration, dateGroupDirectory, resultConfiguration.ResultCollection);
        if (!converted)
        {
            string collectionDirectory = new(result.Replace("<>", resultConfiguration.ResultCollection));
            if (!Directory.Exists(collectionDirectory))
                _ = Directory.CreateDirectory(collectionDirectory);
        }
        string checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription));
        if (!Directory.Exists(checkDirectory))
            _ = Directory.CreateDirectory(checkDirectory);
    }

    internal static string GetResultsFullGroupDirectory(ResultConfiguration resultConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
    {
        string result = GetResultsDateGroupDirectory(resultConfiguration, description);
        if (includeResizeGroup)
            result = Path.Combine(result, outputResolution);
        if (includeModel && includePredictorModel)
        {
            string modelName;
            string predictorModelName;
            if (resultConfiguration.ModelName is null)
                modelName = Model.Hog.ToString();
            else
                modelName = resultConfiguration.ModelName;
            if (resultConfiguration.PredictorModelName is null)
                predictorModelName = PredictorModel.Large.ToString();
            else
                predictorModelName = resultConfiguration.PredictorModelName;
            string dateGroupDirectory = string.Concat(outputResolution.Replace(" ", string.Empty), "-", modelName, "-", predictorModelName, "-", resultConfiguration.NumberOfJitters, "-", resultConfiguration.NumberOfTimesToUpsample);
            result = Path.Combine(result, dateGroupDirectory);
        }
        else if (includeModel)
            throw new Exception();
        else if (includePredictorModel)
            throw new Exception();
        if (!Directory.Exists(result))
            _ = Directory.CreateDirectory(result);
        return result;
    }

    internal static List<string> GetDirectoryInfoCollection(ResultConfiguration resultConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted)
    {
        List<string> results = [];
        string sourceDirectorySegment = GetRelativePath(resultConfiguration, sourceDirectory);
        string result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
        if (!string.IsNullOrEmpty(contentDescription))
            CheckContent(resultConfiguration, dateGroupDirectory, contentDescription, result);
        if (!string.IsNullOrEmpty(singletonDescription))
            CheckSingleton(resultConfiguration, dateGroupDirectory, singletonDescription, converted, result);
        if (!string.IsNullOrEmpty(collectionDescription))
            CheckCollection(resultConfiguration, dateGroupDirectory, collectionDescription, converted, result);
        results.Add(result);
        return results;
    }

    internal static string GetResultsGroupDirectory(ResultConfiguration resultConfiguration, string description, bool create)
    {
        string result = Path.Combine($"{resultConfiguration.RootDirectory}-Results", description.Replace('_', ')'));
        if (create && !Directory.Exists(result))
            _ = Directory.CreateDirectory(result);
        return result;
    }

    internal static List<string> GetDirectoryInfoCollection(ResultConfiguration resultConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
    {
        List<string> results;
        bool converted = false;
        string dateGroupDirectory = GetResultsFullGroupDirectory(resultConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
        results = GetDirectoryInfoCollection(resultConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
        return results;
    }

}