using HanaTui.Hana;
using Spectre.Console;
using SysText = System.Text;

namespace HanaTui.Tui;

/// <summary>
/// Startup screen: lists hdbuserstore keys and lets the user pick one.
/// Returns the selected key name, or null if the user chose to exit.
/// </summary>
public static class KeySelectionScreen
{
    private sealed class KeyChoice
    {
        public string Display { get; init; } = "";
        public string? KeyName { get; init; }  // null = exit, "" = manual entry

        public static readonly KeyChoice Manual = new() { Display = "[ Enter key name manually ]", KeyName = "" };
        public static readonly KeyChoice Exit   = new() { Display = "[ Exit ]",                    KeyName = null };

        public override string ToString() => Display;
    }

    public static string? Run()
    {
        AnsiConsole.Clear();
        AnsiConsole.Write(new FigletText("HANA TUI").Color(Color.DodgerBlue1));
        AnsiConsole.MarkupLine("[dim]SAP HANA Database Manager[/]\n");

        if (!HdbClientLocator.IsAvailable())
        {
            AnsiConsole.MarkupLine("[red][[ERROR]][/] hdbsql not found. " +
                "Ensure the SAP HANA client is installed and on your PATH, " +
                "or present in [dim]/usr/sap/hdbclient[/] or [dim]/usr/sap/NDB/HDB00/exe[/].");
            AnsiConsole.MarkupLine("\nPress any key to exit.");
            Console.ReadKey(intercept: true);
            return null;
        }

        var clientDir = HdbClientLocator.ClientDirectory;
        if (clientDir is not null)
            AnsiConsole.MarkupLine($"[dim]HDB client: {Markup.Escape(clientDir)}[/]\n");

        List<HdbUserstoreKey> keys = [];
        AnsiConsole.Status()
            .Spinner(Spinner.Known.Dots)
            .SpinnerStyle(Style.Parse("blue"))
            .Start("[blue]Loading hdbuserstore keys...[/]", _ =>
            {
                keys = HdbCliRunner.ListKeys();
            });

        if (keys.Count == 0)
        {
            AnsiConsole.MarkupLine("[yellow][[WARN]][/] No hdbuserstore keys found.");
            AnsiConsole.MarkupLine("You can still enter a key name manually.\n");
        }

        // Build typed choices. Display is plain text — never parsed as markup.
        var choices = keys
            .Select(k => new KeyChoice { Display = BuildKeyDisplay(k), KeyName = k.Name })
            .ToList();
        choices.Add(KeyChoice.Manual);
        choices.Add(KeyChoice.Exit);

        var prompt = new SelectionPrompt<KeyChoice>()
            .Title("[bold]Select HDBUSERSTORE key:[/]")
            .PageSize(15)
            .HighlightStyle(Style.Parse("bold dodgerblue1"))
            .UseConverter(c => Markup.Escape(c.Display))
            .AddChoices(choices);

        var selected = AnsiConsole.Prompt(prompt);

        if (selected.KeyName is null)
            return null;  // Exit

        if (selected.KeyName == "")
        {
            var manual = AnsiConsole.Ask<string>("[bold]Enter HDBUSERSTORE key name:[/]").Trim();
            return string.IsNullOrWhiteSpace(manual) ? null : manual;
        }

        return selected.KeyName;
    }

    private static string BuildKeyDisplay(HdbUserstoreKey k)
    {
        var sb = new SysText.StringBuilder(k.Name);

        if (!string.IsNullOrEmpty(k.Host))
        {
            sb.Append("  ");
            sb.Append(k.Host);
            if (!string.IsNullOrEmpty(k.Port))
            {
                sb.Append(':');
                sb.Append(k.Port);
            }
            if (!string.IsNullOrEmpty(k.Tenant))
            {
                sb.Append('@');
                sb.Append(k.Tenant);
            }
        }

        if (!string.IsNullOrEmpty(k.User))
        {
            sb.Append("  user=");
            sb.Append(k.User);
        }

        return sb.ToString();
    }
}
