using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
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 DeleteCommand : Command<DeleteCommand.Settings>
    {
        public sealed class Settings : CommandSettings
        {
            [Description("Paths to Keep.")]
            [DefaultValue(new string[] { "H:\\" })]
            [CommandArgument(1, "[path]")]
            public string[]? FoldersToKeep { get; init; }

            [Description("Path to analyze.")]
            [DefaultValue("redundancies.json")]
            [CommandArgument(0, "[path]")]
            public string? Path { get; init; }

            [Description("File extensions to search for. Comma separated.")]
            [CommandOption("-e|--extensions")]
            [DefaultValue(".jpg,.webp,.raw,.pdf,.xsl,.xslx,.doc,.docx,.txt,.jpeg,.mov,.mp4,.mp3,.wav,.bmp,.gif,.png,.cu,.mid,.msb,.mov,.avi,.wmv,.flv,.m4v,.bak,.cpr,.xml,.psd")]
            public string? Extensions { get; init; }

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

        }
        public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings)
        {
            Global.WriteLine($"[yellow]Analyzing {settings.Path}[/]");

            var redundancies = JsonConvert.DeserializeObject<Dictionary<string, Redundancy>>(File.ReadAllText(settings.Path));

            var pathsToDelete = new List<string>();

            foreach (var redundancy in redundancies.Values)
            {
                var pathToKeep = redundancy.Paths.FirstOrDefault(x => settings.FoldersToKeep.Any(y => x.StartsWith(y)));
                if (pathToKeep != default)
                {

                    foreach (var path in redundancy.Paths)
                    {
                        if (path != pathToKeep)
                        {
                            pathsToDelete.Add(path);
                        }
                    }                    
                }
                else if(settings.Verbose)
                {
                    if (redundancy.Paths.Count > 0)
                    {
                        Global.WriteLine($"[blue]Skipping [/]'{redundancy.Paths.FirstOrDefault()}'[blue]. No paths to keep![/]");
                    }
                    else
                    {
                        Global.WriteLine($"[yellow]Skipping [/]'{redundancy.Hash}'[/].[blue] No paths![/]");
                    }
                    
                }
            }


            foreach (var path in pathsToDelete)
            {
                AnsiConsole.WriteLine(path);
            }
            if (pathsToDelete.Count == 0)
            {
                Global.WriteLine("[yellow]Nothing to delete![/]");

                return 0;
            }
            var confirmation = AnsiConsole.Prompt(
    new TextPrompt<bool>("Delete all of the above?")
        .AddChoice(true)
        .AddChoice(false)
        .DefaultValue(true)
        .WithConverter(choice => choice ? "y" : "n"));

            if (confirmation)
            {
                foreach (var path in pathsToDelete)
                {
                    try
                    {
                        File.Delete(path);
                    }
                    catch (Exception e)
                    {
                        Global.WriteLine($"[red]Error deleting file: [/]'{path}'\nMessage:\n{e.Message}");
                    }

                    Global.WriteLine($"[yellow]Deleted file: [/]'{path}'");
                }
            }
            return 0;
        }

    }
}
