using HanaTui.Hana;
using HanaTui.Tui;

// -----------------------------------------------------------------------
// Entry point
// -----------------------------------------------------------------------

// Enable UTF-8 output for block characters in bars
Console.OutputEncoding = System.Text.Encoding.UTF8;

// Key selection loop — allows returning to key picker via "Change Key"
string? keyName = null;
HdbUserstoreKey? keyObj = null;

while (true)
{
    // Step 1: Select or re-select a key
    keyName = KeySelectionScreen.Run();
    if (keyName is null)
    {
        // User chose Exit
        break;
    }

    // Resolve key metadata if available
    keyObj = HdbCliRunner.ListKeys().Find(k => k.Name.Equals(keyName, StringComparison.OrdinalIgnoreCase));

    // Step 2: Main menu loop for this key
    var exitToKeySelection = false;
    while (!exitToKeySelection)
    {
        var operation = MainMenuScreen.Run(keyObj, keyName);

        switch (operation)
        {
            case MainMenuScreen.Operation.Quit:
                Environment.Exit(0);
                break;

            case MainMenuScreen.Operation.ChangeKey:
                exitToKeySelection = true;
                break;

            case MainMenuScreen.Operation.Export:
                await HandleExportAsync(keyName);
                break;

            case MainMenuScreen.Operation.Import:
                await HandleImportAsync(keyName, renameMode: false);
                break;

            case MainMenuScreen.Operation.ImportRename:
                await HandleImportAsync(keyName, renameMode: true);
                break;

            case MainMenuScreen.Operation.Copy:
                await HandleCopyAsync(keyName);
                break;

            case MainMenuScreen.Operation.Drop:
                await HandleDropAsync(keyName);
                break;

            case MainMenuScreen.Operation.RenameDb:
                await HandleRenameDbAsync(keyName);
                break;

            case MainMenuScreen.Operation.Backup:
                await HandleBackupAsync(keyName);
                break;
        }
    }
}

return;

// -----------------------------------------------------------------------
// Operation handlers
// -----------------------------------------------------------------------

static async Task HandleExportAsync(string key)
{
    var p = OperationForms.ExportForm(key);
    if (p is null) return;

    var svc = new SchemaService(key);
    await TaskRunnerScreen.RunAsync(
        $"Export Schema '{p.Schema}'",
        (log, ct) => svc.ExportAsync(p, log, ct));
}

static async Task HandleImportAsync(string key, bool renameMode)
{
    var p = OperationForms.ImportForm(key, renameMode);
    if (p is null) return;

    var svc = new SchemaService(key);
    await TaskRunnerScreen.RunAsync(
        renameMode ? $"Import & Rename '{p.SourceSchema}'" : $"Import '{p.SourceSchema}'",
        (log, ct) => svc.ImportAsync(p, log, ct));
}

static async Task HandleCopyAsync(string key)
{
    var p = OperationForms.CopyForm(key);
    if (p is null) return;

    var svc = new SchemaService(key);
    await TaskRunnerScreen.RunAsync(
        $"Copy '{p.SourceSchema}' -> '{p.TargetSchema}'",
        (log, ct) => svc.CopyAsync(p, log, ct));
}

static async Task HandleDropAsync(string key)
{
    var p = OperationForms.DropForm(key);
    if (p is null) return;

    var svc = new SchemaService(key);
    await TaskRunnerScreen.RunAsync(
        $"Drop Schema '{p.Schema}'",
        (log, ct) => svc.DropAsync(p, log, ct));
}

static async Task HandleRenameDbAsync(string key)
{
    var p = OperationForms.RenameDbForm(key);
    if (p is null) return;

    var svc = new SchemaService(key);
    await TaskRunnerScreen.RunAsync(
        $"Rename DB '{p.Schema}'",
        (log, ct) => svc.RenameDbAsync(p, log, ct));
}

static async Task HandleBackupAsync(string key)
{
    var p = OperationForms.BackupForm(key);
    if (p is null) return;

    var svc = new SchemaService(key);
    await TaskRunnerScreen.RunAsync(
        "Backup Tenant",
        (log, ct) => svc.BackupAsync(p, log, ct));
}
