using File_Watcher.Models;
using System.Globalization;

namespace File_Watcher.Helpers;

internal static partial class HelperMetrologyFiles
{

    private static void Sort(MetrologyConfiguration metrologyConfiguration, ILogger<Worker> logger, Calendar calendar)
    {
        bool check;
        string lines;
        int weekOfYear;
        string[] files;
        string checkFile;
        string directory;
        FileInfo fileInfo;
        string checkDirectory;
        DateTime dateTime = DateTime.Now;
        foreach (string sourceDirectory in metrologyConfiguration.SourceDirectories)
        {
            files = Directory.GetFiles(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
            foreach (string file in files)
            {
                check = false;
                fileInfo = new(file);
                if (fileInfo.LastWriteTime > dateTime)
                    continue;
                directory = Path.GetDirectoryName(file) ?? throw new Exception();
                for (int i = 0; i < metrologyConfiguration.DirectoriesBack; i++)
                    directory = Path.GetDirectoryName(directory) ?? throw new Exception();
                weekOfYear = calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
                for (int i = 1; i < 3; i++)
                {
                    if (check)
                        break;
                    lines = i switch
                    {
                        1 => fileInfo.Name,
                        2 => File.ReadAllText(file),
                        _ => throw new NotImplementedException()
                    };
                    foreach (string hardcodedValue in metrologyConfiguration.HardcodedValues)
                    {
                        if (!lines.Contains(hardcodedValue))
                            continue;
                        checkDirectory = Path.Combine(directory, $"{fileInfo.LastWriteTime:yyyy}_Week_{weekOfYear:00}", fileInfo.LastWriteTime.ToString("yyyy-MM-dd"), hardcodedValue);
                        if (!Directory.Exists(checkDirectory))
                            _ = Directory.CreateDirectory(checkDirectory);
                        checkFile = Path.Combine(checkDirectory, Path.GetFileName(file));
                        if (File.Exists(checkFile) || !File.Exists(file))
                            continue;
                        try
                        { File.Move(file, checkFile); }
                        catch (Exception) { }
                        check = true;
                        break;
                    }
                }
            }
            logger.LogInformation("{sourceDirectory}", sourceDirectory);
        }
    }

    private static void Delete(MetrologyConfiguration metrologyConfiguration, ILogger<Worker> logger)
    {
        string directory;
        DateTime dateTime;
        string[] directories;
        DirectoryInfo directoryInfo;
        string yearWeekFormat = "yyyy_Week_00";
        DateTime deleteBefore = DateTime.Now.AddDays(-7 * metrologyConfiguration.DeleteOlderThanWeeks);
        foreach (string sourceDirectory in metrologyConfiguration.SourceDirectories)
        {
            directory = sourceDirectory;
            for (int i = 0; i < metrologyConfiguration.DirectoriesBack; i++)
                directory = Path.GetDirectoryName(directory) ?? throw new Exception();
            directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
            foreach (string weekOfYearDirectory in directories)
            {
                directoryInfo = new(weekOfYearDirectory);
                if (directoryInfo.Name.Length != yearWeekFormat.Length)
                    continue;
                if (!int.TryParse(directoryInfo.Name[..4], out int year))
                    continue;
                if (!int.TryParse(directoryInfo.Name[^2..], out int week))
                    continue;
                dateTime = new(year, 1, 1);
                dateTime = dateTime.AddDays(week * 7).AddSeconds(-1);
                if (directoryInfo.LastWriteTime != dateTime)
                    Directory.SetLastWriteTime(directoryInfo.FullName, dateTime);
                if (dateTime > deleteBefore)
                    continue;
                Directory.Delete(weekOfYearDirectory, recursive: true);
            }
            logger.LogInformation("{sourceDirectory}", sourceDirectory);
        }
    }

    internal static bool SortAndDelete(AppSettings appSettings, ILogger<Worker> logger)
    {
        CultureInfo cultureInfo = new("en-US");
        Calendar calendar = cultureInfo.Calendar;
        Sort(appSettings.MetrologyConfiguration, logger, calendar);
        Delete(appSettings.MetrologyConfiguration, logger);
        return true;
    }

}