using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RedundancyFinder;
using Spectre.Console;
using Spectre.Console.Cli;
namespace RedundancyFinderCLI
{
    internal sealed class SanitizeCommand : Command<SanitizeCommand.Settings>
    {
        public sealed class Settings : CommandSettings
        {
            [Description("Path to sanitize.")]
            [CommandArgument(0, "[path]")]
            public string? Path { get; init; }

            [Description("Show all information.")]
            [CommandOption("-v|--verbose")]
            [DefaultValue(false)]
            public bool Verbose { get; init; }

            [Description("Show all information.")]
            [CommandOption("-d|--deleteNonExistent <pathToSource>")]
            [DefaultValue("redundancies.json")]
            public string? PathToSource { get; init; }

        }

        Settings settings = null;
        public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings)
        {
            this.settings = settings;
            Global.WriteLine($"[white]Sanitizing {settings.Path}[/]");
            Global.WriteLine($"[yellow]Deleting empty folders[/]");
            int count = DeleteEmptyFolders(settings.Path);
            if (File.Exists(settings.PathToSource))
            {
                DeleteNonExistentPaths();
            }
            Global.WriteLine($"[green]Deleted [/]{count}[green] empty folders[/]");

            return 0;
        }

        public void DeleteNonExistentPaths()
        {
            Dictionary<string, Redundancy> redundancies = null;


            AnsiConsole.Status()
    .Start($"[yellow]Loading [/]'{settings.PathToSource}'", ctx =>
    {
        ctx.Spinner(Spinner.Known.Clock);
        ctx.SpinnerStyle = Style.Parse("yellow bold");
        Thread.Sleep(1000);
        redundancies = JsonConvert.DeserializeObject<Dictionary<string, Redundancy>>(File.ReadAllText(settings.PathToSource));

    });

            foreach (var redundancy in redundancies)
            {
                var paths = redundancy.Value.Paths;
                foreach (var path in paths.ToList())
                {
                    Global.WriteLine($"[green]Checking file: {path}[/]");

                    if (!File.Exists(path))
                    {
                        Global.WriteLine($"[red]Deleting non existent file: {path}[/]");

                        redundancy.Value.Paths.Remove(path);
                    }
                }
            }

            var json = JsonConvert.SerializeObject(redundancies, Formatting.Indented);
            File.WriteAllText(settings.PathToSource, json);
        }


        public static int DeleteEmptyFolders(string directoryPath, int count = 0)
        {
            try
            {
                // Get all subdirectories
                foreach (var subDirectory in Directory.GetDirectories(directoryPath))
                {
                    // Recursively delete empty folders in subdirectories
                    count = DeleteEmptyFolders(subDirectory, count);
                }

                // Check if the current directory is empty
                if (Directory.GetFiles(directoryPath).Length == 0 && Directory.GetDirectories(directoryPath).Length == 0)
                {
                    Directory.Delete(directoryPath);
                    count++;
                    Global.WriteLine($"Deleted empty folder: {directoryPath}");
                }
            }
            catch (Exception ex)
            {
                Global.WriteLine($"[red]Error deleting folder [/]'{directoryPath}':\n [red]{ex.Message}[/]");
            }

            return count;
        }


    }
}
