import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
import { createInfoEmbed, createSuccessEmbed, createWarningEmbed, createErrorEmbed } from "@lib/embeds";
import type { UpdateInfo, UpdateCheckResult } from "./update.types";

// Constants for UI
const LOG_TRUNCATE_LENGTH = 800;
const OUTPUT_TRUNCATE_LENGTH = 400;

function truncate(text: string, maxLength: number): string {
    if (!text) return "";
    return text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
}

// ============ Pre-Update Embeds ============

export function getCheckingEmbed() {
    return createInfoEmbed("🔍 Fetching latest changes from remote...", "Checking for Updates");
}

export function getNoUpdatesEmbed(currentCommit: string) {
    return createSuccessEmbed(
        `You're running the latest version.\n\n**Current:** \`${currentCommit}\``,
        "✅ Already Up to Date"
    );
}

export function getUpdatesAvailableMessage(
    updateInfo: UpdateInfo,
    requirements: UpdateCheckResult,
    changeCategories: Record<string, number>,
    force: boolean
) {
    const { branch, currentCommit, latestCommit, commitCount, commits } = updateInfo;
    const { needsRootInstall, needsWebInstall, needsWebBuild, needsMigrations } = requirements;

    // Build commit list (max 5)
    const commitList = commits
        .slice(0, 5)
        .map(c => `\`${c.hash}\` ${truncate(c.message, 50)}`)
        .join("\n");

    const moreCommits = commitCount > 5 ? `\n*...and ${commitCount - 5} more*` : "";

    // Build change categories
    const categoryList = Object.entries(changeCategories)
        .map(([cat, count]) => `• ${cat}: ${count} file${count > 1 ? "s" : ""}`)
        .join("\n");

    // Build requirements list
    const reqs: string[] = [];
    if (needsRootInstall) reqs.push("📦 Install root dependencies");
    if (needsWebInstall) reqs.push("🌐 Install web dependencies");
    if (needsWebBuild) reqs.push("🏗️ Build web dashboard");
    if (needsMigrations) reqs.push("🗃️ Run database migrations");
    if (reqs.length === 0) reqs.push("⚡ Quick update (no extra steps)");

    const embed = new EmbedBuilder()
        .setTitle("📥 Updates Available")
        .setColor(force ? 0xFF6B6B : 0x5865F2)
        .addFields(
            {
                name: "Version",
                value: `\`${currentCommit}\` → \`${latestCommit}\``,
                inline: true
            },
            {
                name: "Branch",
                value: `\`${branch}\``,
                inline: true
            },
            {
                name: "Commits",
                value: `${commitCount} new commit${commitCount > 1 ? "s" : ""}`,
                inline: true
            },
            {
                name: "Recent Changes",
                value: commitList + moreCommits || "No commits",
                inline: false
            },
            {
                name: "Files Changed",
                value: categoryList || "Unknown",
                inline: true
            },
            {
                name: "Update Actions",
                value: reqs.join("\n"),
                inline: true
            }
        )
        .setFooter({ text: force ? "⚠️ Force mode enabled" : "This will restart the bot" })
        .setTimestamp();

    const confirmButton = new ButtonBuilder()
        .setCustomId("confirm_update")
        .setLabel(force ? "Force Update" : "Update Now")
        .setEmoji(force ? "⚠️" : "🚀")
        .setStyle(force ? ButtonStyle.Danger : ButtonStyle.Success);

    const cancelButton = new ButtonBuilder()
        .setCustomId("cancel_update")
        .setLabel("Cancel")
        .setStyle(ButtonStyle.Secondary);

    const row = new ActionRowBuilder<ButtonBuilder>().addComponents(confirmButton, cancelButton);

    return { embeds: [embed], components: [row] };
}

// ============ Update Progress Embeds ============

export function getPreparingEmbed() {
    return createInfoEmbed(
        "🔒 Saving rollback point...\n📥 Preparing to download updates...",
        "⏳ Preparing Update"
    );
}

export function getUpdatingEmbed(requirements: UpdateCheckResult) {
    const steps: string[] = ["✅ Rollback point saved"];

    steps.push("📥 Downloading updates...");

    if (requirements.needsRootInstall || requirements.needsWebInstall) {
        steps.push("📦 Dependencies will be installed after restart");
    }
    if (requirements.needsWebBuild) {
        steps.push("🏗️ Web dashboard will be rebuilt after restart");
    }
    if (requirements.needsMigrations) {
        steps.push("🗃️ Migrations will run after restart");
    }

    steps.push("\n🔄 **Restarting now...**");

    return createWarningEmbed(steps.join("\n"), "🚀 Updating");
}

export function getCancelledEmbed() {
    return createInfoEmbed("Update cancelled. No changes were made.", "❌ Cancelled");
}

export function getTimeoutEmbed() {
    return createWarningEmbed(
        "No response received within 30 seconds.\nRun `/update` again when ready.",
        "⏰ Timed Out"
    );
}

export function getErrorEmbed(error: unknown) {
    const message = error instanceof Error ? error.message : String(error);
    return createErrorEmbed(
        `The update could not be completed:\n\`\`\`\n${truncate(message, 500)}\n\`\`\``,
        "❌ Update Failed"
    );
}

// ============ Post-Restart Embeds ============

export interface PostRestartResult {
    installSuccess: boolean;
    installOutput: string;
    webBuildSuccess: boolean;
    webBuildOutput: string;
    migrationSuccess: boolean;
    migrationOutput: string;
    ranInstall: boolean;
    ranWebBuild: boolean;
    ranMigrations: boolean;
    previousCommit?: string;
    newCommit?: string;
}

export function getPostRestartEmbed(result: PostRestartResult, hasRollback: boolean) {
    const isSuccess = result.installSuccess && result.webBuildSuccess && result.migrationSuccess;

    const embed = new EmbedBuilder()
        .setTitle(isSuccess ? "✅ Update Complete" : "⚠️ Update Completed with Issues")
        .setColor(isSuccess ? 0x57F287 : 0xFEE75C)
        .setTimestamp();

    // Version info
    if (result.previousCommit && result.newCommit) {
        embed.addFields({
            name: "Version",
            value: `\`${result.previousCommit}\` → \`${result.newCommit}\``,
            inline: false
        });
    }

    // Results summary
    const results: string[] = [];

    if (result.ranInstall) {
        results.push(result.installSuccess
            ? "✅ Dependencies installed"
            : "❌ Dependency installation failed"
        );
    }

    if (result.ranWebBuild) {
        results.push(result.webBuildSuccess
            ? "✅ Web dashboard built"
            : "❌ Web dashboard build failed"
        );
    }

    if (result.ranMigrations) {
        results.push(result.migrationSuccess
            ? "✅ Migrations applied"
            : "❌ Migration failed"
        );
    }

    if (results.length > 0) {
        embed.addFields({
            name: "Actions Performed",
            value: results.join("\n"),
            inline: false
        });
    }

    // Output details (collapsed if too long)
    if (result.installOutput && !result.installSuccess) {
        embed.addFields({
            name: "Install Output",
            value: `\`\`\`\n${truncate(result.installOutput, OUTPUT_TRUNCATE_LENGTH)}\n\`\`\``,
            inline: false
        });
    }

    if (result.webBuildOutput && !result.webBuildSuccess) {
        embed.addFields({
            name: "Web Build Output",
            value: `\`\`\`\n${truncate(result.webBuildOutput, OUTPUT_TRUNCATE_LENGTH)}\n\`\`\``,
            inline: false
        });
    }

    if (result.migrationOutput && !result.migrationSuccess) {
        embed.addFields({
            name: "Migration Output",
            value: `\`\`\`\n${truncate(result.migrationOutput, OUTPUT_TRUNCATE_LENGTH)}\n\`\`\``,
            inline: false
        });
    }

    // Footer with rollback hint
    if (!isSuccess && hasRollback) {
        embed.setFooter({ text: "💡 Use /update rollback to revert if needed" });
    }

    // Build components
    const components: ActionRowBuilder<ButtonBuilder>[] = [];

    if (!isSuccess && hasRollback) {
        const rollbackButton = new ButtonBuilder()
            .setCustomId("rollback_update")
            .setLabel("Rollback")
            .setEmoji("↩️")
            .setStyle(ButtonStyle.Danger);

        components.push(new ActionRowBuilder<ButtonBuilder>().addComponents(rollbackButton));
    }

    return { embeds: [embed], components };
}

export function getInstallingDependenciesEmbed() {
    return createInfoEmbed(
        "📦 Installing dependencies for root and web projects...\nThis may take a moment.",
        "⏳ Installing Dependencies"
    );
}

export function getRunningMigrationsEmbed() {
    return createInfoEmbed(
        "🗃️ Applying database migrations...",
        "⏳ Running Migrations"
    );
}

export function getBuildingWebEmbed() {
    return createInfoEmbed(
        "🌐 Building web dashboard assets...\nThis may take a moment.",
        "⏳ Building Web Dashboard"
    );
}

export interface PostRestartProgress {
    installDeps: boolean;
    buildWeb: boolean;
    runMigrations: boolean;
    currentStep: "starting" | "install" | "build" | "migrate" | "done";
    installDone?: boolean;
    buildDone?: boolean;
    migrateDone?: boolean;
}

export function getPostRestartProgressEmbed(progress: PostRestartProgress) {
    const steps: string[] = [];

    // Installation step
    if (progress.installDeps) {
        if (progress.currentStep === "install") {
            steps.push("⏳ Installing dependencies...");
        } else if (progress.installDone) {
            steps.push("✅ Dependencies installed");
        } else {
            steps.push("⬚ Install dependencies");
        }
    }

    // Web build step
    if (progress.buildWeb) {
        if (progress.currentStep === "build") {
            steps.push("⏳ Building web dashboard...");
        } else if (progress.buildDone) {
            steps.push("✅ Web dashboard built");
        } else {
            steps.push("⬚ Build web dashboard");
        }
    }

    // Migrations step
    if (progress.runMigrations) {
        if (progress.currentStep === "migrate") {
            steps.push("⏳ Running migrations...");
        } else if (progress.migrateDone) {
            steps.push("✅ Migrations applied");
        } else {
            steps.push("⬚ Run migrations");
        }
    }

    if (steps.length === 0) {
        steps.push("⚡ Quick restart (no extra steps needed)");
    }

    return createInfoEmbed(steps.join("\n"), "🔄 Post-Update Tasks");
}

export function getRollbackSuccessEmbed(commit: string) {
    return createSuccessEmbed(
        `Successfully rolled back to commit \`${commit}\`.\nThe bot will restart now.`,
        "↩️ Rollback Complete"
    );
}

export function getRollbackFailedEmbed(error: string) {
    return createErrorEmbed(
        `Could not rollback:\n\`\`\`\n${error}\n\`\`\``,
        "❌ Rollback Failed"
    );
}
