import {
    ActionRowBuilder,
    ButtonBuilder,
    ButtonStyle,
    ContainerBuilder,
    TextDisplayBuilder,
    SeparatorBuilder,
    SeparatorSpacingSize,
    MessageFlags
} from "discord.js";
import { QUEST_CUSTOM_IDS } from "./quest.types";

/**
 * Quest entry with quest details and progress
 */
interface QuestEntry {
    progress: number | null;
    completedAt: Date | null;
    quest: {
        id: number;
        name: string;
        description: string | null;
        triggerEvent: string;
        requirements: any;
        rewards: any;
    };
}

/**
 * Available quest interface
 */
interface AvailableQuest {
    id: number;
    name: string;
    description: string | null;
    rewards: any;
    requirements: any;
}

// Color palette for containers
const COLORS = {
    ACTIVE: 0x3498db,    // Blue - in progress
    AVAILABLE: 0x2ecc71, // Green - available
    COMPLETED: 0xf1c40f  // Gold - completed
};

// Max quests per page. Discord counts all nested components toward a 40 total limit:
// Fixed: 1 container + 2 header + 1 nav row + 2 nav buttons + 1 pagination row + 2 pagination buttons = 9
// Per quest (available): 1 separator + 3 text + 1 action row + 1 button = 6
// Budget: 9 + 6×5 = 39 <= 40
const QUESTS_PER_PAGE = 5;

/**
 * Formats quest rewards object into a human-readable string
 */
function formatQuestRewards(rewards: { xp?: number, balance?: number }): string {
    const rewardStr: string[] = [];
    if (rewards?.xp) rewardStr.push(`${rewards.xp} XP`);
    if (rewards?.balance) rewardStr.push(`${rewards.balance} 🪙`);
    return rewardStr.join(" • ") || "None";
}

/**
 * Renders a simple progress bar
 */
function renderProgressBar(current: number, total: number, size: number = 10): string {
    const percentage = Math.min(current / total, 1);
    const progress = Math.round(size * percentage);
    const empty = size - progress;

    const progressText = "▰".repeat(progress);
    const emptyText = "▱".repeat(empty);

    return `${progressText}${emptyText} ${Math.round(percentage * 100)}%`;
}

/**
 * Creates Components v2 containers for the quest list (active quests only)
 */
export function getQuestListComponents(userQuests: QuestEntry[], page: number = 0): ContainerBuilder[] {
    // Filter to only show in-progress quests (not completed)
    const activeQuests = userQuests.filter(entry => entry.completedAt === null);
    const totalPages = Math.max(1, Math.ceil(activeQuests.length / QUESTS_PER_PAGE));
    const safePage = Math.min(page, totalPages - 1);
    const pageQuests = activeQuests.slice(safePage * QUESTS_PER_PAGE, (safePage + 1) * QUESTS_PER_PAGE);

    const container = new ContainerBuilder()
        .setAccentColor(COLORS.ACTIVE)
        .addTextDisplayComponents(
            new TextDisplayBuilder().setContent("# 📜 Quest Log"),
            new TextDisplayBuilder().setContent(
                totalPages > 1
                    ? `-# Your active quests — Page ${safePage + 1}/${totalPages}`
                    : "-# Your active quests"
            )
        );

    if (activeQuests.length === 0) {
        container.addSeparatorComponents(new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small));
        container.addTextDisplayComponents(
            new TextDisplayBuilder().setContent("*You have no active quests. Check available quests!*")
        );
        return [container];
    }

    pageQuests.forEach((entry) => {
        container.addSeparatorComponents(new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small));

        const rewards = entry.quest.rewards as { xp?: number, balance?: number };
        const rewardsText = formatQuestRewards(rewards);

        const requirements = entry.quest.requirements as { target?: number };
        const target = requirements?.target || 1;
        const progress = entry.progress || 0;
        const progressBar = renderProgressBar(progress, target);

        container.addTextDisplayComponents(
            new TextDisplayBuilder().setContent(`**${entry.quest.name}**`),
            new TextDisplayBuilder().setContent(entry.quest.description || "*No description*"),
            new TextDisplayBuilder().setContent(`📊 ${progressBar} \`${progress}/${target}\`  •  🎁 ${rewardsText}`)
        );
    });

    return [container];
}

/**
 * Creates Components v2 containers for available quests with inline accept buttons
 */
export function getAvailableQuestsComponents(availableQuests: AvailableQuest[], page: number = 0): ContainerBuilder[] {
    const totalPages = Math.max(1, Math.ceil(availableQuests.length / QUESTS_PER_PAGE));
    const safePage = Math.min(page, totalPages - 1);
    const pageQuests = availableQuests.slice(safePage * QUESTS_PER_PAGE, (safePage + 1) * QUESTS_PER_PAGE);

    const container = new ContainerBuilder()
        .setAccentColor(COLORS.AVAILABLE)
        .addTextDisplayComponents(
            new TextDisplayBuilder().setContent("# 🗺️ Available Quests"),
            new TextDisplayBuilder().setContent(
                totalPages > 1
                    ? `-# Quests you can accept — Page ${safePage + 1}/${totalPages}`
                    : "-# Quests you can accept"
            )
        );

    if (availableQuests.length === 0) {
        container.addSeparatorComponents(new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small));
        container.addTextDisplayComponents(
            new TextDisplayBuilder().setContent("*No new quests available at the moment.*")
        );
        return [container];
    }

    pageQuests.forEach((quest) => {
        container.addSeparatorComponents(new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small));

        const rewards = quest.rewards as { xp?: number, balance?: number };
        const rewardsText = formatQuestRewards(rewards);

        const requirements = quest.requirements as { target?: number };
        const target = requirements?.target || 1;

        container.addTextDisplayComponents(
            new TextDisplayBuilder().setContent(`**${quest.name}**`),
            new TextDisplayBuilder().setContent(quest.description || "*No description*"),
            new TextDisplayBuilder().setContent(`🎯 Goal: \`${target}\`  •  🎁 ${rewardsText}`)
        );

        // Add accept button inline within the container
        container.addActionRowComponents(
            new ActionRowBuilder<ButtonBuilder>().addComponents(
                new ButtonBuilder()
                    .setCustomId(QUEST_CUSTOM_IDS.ACCEPT(quest.id))
                    .setLabel("Accept Quest")
                    .setStyle(ButtonStyle.Success)
                    .setEmoji("✅")
            )
        );
    });

    return [container];
}

/**
 * Returns action rows for navigation and pagination
 */
export function getQuestActionRows(viewType: 'active' | 'available', totalItems: number, page: number): ActionRowBuilder<ButtonBuilder>[] {
    const totalPages = Math.max(1, Math.ceil(totalItems / QUESTS_PER_PAGE));
    const rows: ActionRowBuilder<ButtonBuilder>[] = [];

    // Pagination row (only if more than one page)
    if (totalPages > 1) {
        rows.push(new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId(QUEST_CUSTOM_IDS.PAGE_PREV)
                .setLabel("◀ Prev")
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(page <= 0),
            new ButtonBuilder()
                .setCustomId(QUEST_CUSTOM_IDS.PAGE_NEXT)
                .setLabel("Next ▶")
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(page >= totalPages - 1)
        ));
    }

    // Tab navigation row
    rows.push(new ActionRowBuilder<ButtonBuilder>().addComponents(
        new ButtonBuilder()
            .setCustomId(QUEST_CUSTOM_IDS.VIEW_ACTIVE)
            .setLabel("📜 Active")
            .setStyle(viewType === 'active' ? ButtonStyle.Primary : ButtonStyle.Secondary)
            .setDisabled(viewType === 'active'),
        new ButtonBuilder()
            .setCustomId(QUEST_CUSTOM_IDS.VIEW_AVAILABLE)
            .setLabel("🗺️ Available")
            .setStyle(viewType === 'available' ? ButtonStyle.Primary : ButtonStyle.Secondary)
            .setDisabled(viewType === 'available')
    ));

    return rows;
}

/**
 * Creates Components v2 celebratory message for quest completion
 */
export function getQuestCompletionComponents(quest: any, rewards: { xp: bigint, balance: bigint }): ContainerBuilder[] {
    const rewardsText = formatQuestRewards({
        xp: Number(rewards.xp),
        balance: Number(rewards.balance)
    });

    const container = new ContainerBuilder()
        .setAccentColor(COLORS.COMPLETED)
        .addTextDisplayComponents(
            new TextDisplayBuilder().setContent("# 🎉 Quest Completed!"),
            new TextDisplayBuilder().setContent(`Congratulations! You've completed **${quest.name}**`)
        )
        .addSeparatorComponents(new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small))
        .addTextDisplayComponents(
            new TextDisplayBuilder().setContent(`📝 ${quest.description || "No description provided."}`),
            new TextDisplayBuilder().setContent(`🎁 **Rewards Earned:** ${rewardsText}`)
        );

    return [container];
}

/**
 * Gets MessageFlags and allowedMentions for Components v2 messages
 */
export function getComponentsV2MessageFlags() {
    return {
        flags: MessageFlags.IsComponentsV2,
        allowedMentions: { parse: [] as const }
    };
}
