using File_Folder_Helper.Models;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace File_Folder_Helper;

public class Worker : BackgroundService
{

    private readonly bool _IsSilent;
    private readonly List<string> _Args;
    private readonly ILogger<Worker> _Logger;
    private readonly AppSettings _AppSettings;
    private readonly ConsoleKey[] _ConsoleKeys;
    private readonly IHostApplicationLifetime _Lifetime;

    public Worker(ILogger<Worker> logger, IHostApplicationLifetime lifetime, List<string> args, AppSettings appSettings)
    {
        _Args = args;
        _Logger = logger;
        _Lifetime = lifetime;
        _AppSettings = appSettings;
        int silentIndex = args.IndexOf("s");
        _IsSilent = silentIndex > -1;
        if (_IsSilent)
            args.RemoveAt(silentIndex);
        _ConsoleKeys = new ConsoleKey[]
        {
            ConsoleKey.A,
            ConsoleKey.B,
            ConsoleKey.C,
            ConsoleKey.D,
            ConsoleKey.E,
            ConsoleKey.F,
            ConsoleKey.H,
            ConsoleKey.J,
            ConsoleKey.K,
            ConsoleKey.L,
            ConsoleKey.M,
            ConsoleKey.N,
            ConsoleKey.R,
            ConsoleKey.S,
            ConsoleKey.T,
            ConsoleKey.U,
            ConsoleKey.Z,
            ConsoleKey.Delete
        };
    }

    public override Task StartAsync(CancellationToken cancellationToken) =>
        base.StartAsync(cancellationToken);

    public override Task StopAsync(CancellationToken cancellationToken) =>
        base.StopAsync(cancellationToken);

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        if (!stoppingToken.IsCancellationRequested)
            await Task.Delay(500, stoppingToken);
        if (_AppSettings is null)
            throw new NullReferenceException(nameof(_AppSettings));
        try
        {
            int? singleCharIndex = null;
            ConsoleKey consoleKey = ConsoleKey.End;
            for (int i = 0; i < _Args.Count; i++)
            {
                if (_Args[i].Length == 1 && Enum.TryParse(_Args[i], out consoleKey) && _ConsoleKeys.Contains(consoleKey))
                {
                    singleCharIndex = i;
                    break;
                }
            }
            if (consoleKey is not ConsoleKey.End && !_ConsoleKeys.Contains(consoleKey))
                consoleKey = ConsoleKey.End;
            if (singleCharIndex is not null)
                _Args.RemoveAt(singleCharIndex.Value);
            if (!_Args.Any())
                _Logger.LogInformation("Must pass a argument!");
            else if (_Args[0].EndsWith(".kanbn") && Directory.Exists(_Args[0]))
                Helpers.HelperKanbanMetadata.SetMetadata(_Logger, _AppSettings, _Args[0]);
            else if (Directory.Exists(_Args[0]) && File.Exists(Path.Combine(_Args[0], string.Concat(Path.GetFileName(_Args[0]), ".dll"))))
                Helpers.HelperILMerge.ILMerge(_Args[0]);
            else if (Directory.Exists(_Args[0]))
            {
                for (int i = 0; i < int.MaxValue; i++)
                {
                    if (_ConsoleKeys.Contains(consoleKey))
                        break;
                    _Logger.LogInformation("A) Save (Top Directory Only),");
                    _Logger.LogInformation("B) Save (All Directories),");
                    _Logger.LogInformation("C) Clipboard (Top Directory Only),");
                    _Logger.LogInformation("D) Clipboard (All Directories),");
                    _Logger.LogInformation("E) Clipboard (Top Directory Only and File Name Without Extension),");
                    _Logger.LogInformation("F) Clipboard (All Directories and File Name Without Extension),");
                    _Logger.LogInformation("H) Hardcoded file search and sort,");
                    _Logger.LogInformation("J) Set Date from Json Entry");
                    _Logger.LogInformation("K) Kanban support");
                    _Logger.LogInformation("L) Log Merge (APC Log [0-9(8)]_*.log),");
                    _Logger.LogInformation("N) Create Note Files,");
                    _Logger.LogInformation("M) Markdown Wiki Link Verification,");
                    _Logger.LogInformation("R) Rename to old, copy, delete old");
                    _Logger.LogInformation("S) Set Date from Zip Entry");
                    _Logger.LogInformation("T) Too long rename");
                    _Logger.LogInformation("U) Links for Hugo");
                    _Logger.LogInformation("Z) Zip file(s) by date,");
                    _Logger.LogInformation("Delete) Delete empty directories,");
                    consoleKey = Console.ReadKey().Key;
                    _Logger.LogInformation(" ");
                }
                switch (consoleKey)
                {
                    case ConsoleKey.A:
                    case ConsoleKey.B:
                    case ConsoleKey.C:
                    case ConsoleKey.E:
                    case ConsoleKey.F:
                        Helpers.HelperSaveOrCopyContents.SaveOrCopyContents(_Logger, _Args[0], consoleKey);
                        break;
                    case ConsoleKey.H:
                        Helpers.HelperHardcodedFileSearchAndSort.HardcodedFileSearchAndSort(_Logger, _Args[0]);
                        break;
                    case ConsoleKey.J:
                        Helpers.HelperPackageFilesByDate.SetDateFromJsonEntry(_Logger, _Args[0]);
                        break;
                    case ConsoleKey.K:
                        Helpers.HelperKanbanMetadata.SetMetadata(_Logger, _AppSettings, _Args[0]);
                        break;
                    case ConsoleKey.L:
                        Helpers.HelperLogMerge.LogMerge(_Args[0]);
                        break;
                    case ConsoleKey.N:
                        Helpers.HelperCreateNoteFiles.CreateNoteFiles(_Args[0]);
                        break;
                    case ConsoleKey.M:
                        Helpers.HelperMarkdown.MarkdownWikiLinkVerification(_AppSettings, _Logger, _Args);
                        break;
                    case ConsoleKey.R:
                        Helpers.HelperRenameToOldMoveDeleteOldMerge.RenameToOldMoveDeleteOld(_Logger, _Args[0]);
                        break;
                    case ConsoleKey.S:
                        Helpers.HelperZipFilesByDate.SetDateFromZipEntry(_Logger, _Args[0]);
                        break;
                    case ConsoleKey.T:
                        Helpers.HelperTooLong.TooLong(_Args[0], delete: false);
                        Helpers.HelperTooLong.TooLong(_Args[0], delete: true);
                        break;
                    case ConsoleKey.U:
                        Helpers.HelperMarkdown.MarkdownConvertLinksForHugo(_AppSettings, _Logger, _Args);
                        break;
                    case ConsoleKey.Z:
                        Helpers.HelperZipFilesByDate.ZipFilesByDate(_Logger, _Args[0]);
                        break;
                    default:
                        switch (consoleKey)
                        {
                            case ConsoleKey.Delete:
                                for (int j = 1; j < 6; j++)
                                {
                                    if (!Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(_Args[0]))
                                        break;
                                }
                                break;
                            default:
                                throw new Exception();
                        }
                        break;
                }
            }
            else
                throw new Exception(_Args[0]);
        }
        catch (Exception ex)
        { _Logger.LogError(string.Concat(ex.Message, Environment.NewLine, ex.StackTrace)); }
        if (_IsSilent)
            _Logger.LogInformation("Done. Bye");
        else
        {
            _Logger.LogInformation("Done. Press 'Enter' to end");
            _ = Console.ReadLine();
        }
        _Lifetime.StopApplication();
    }

}