import type { 
    LevelingConfig, 
    EconomyConfig as EconomyConfigDB, 
    InventoryConfig as InventoryConfigDB, 
    LootdropConfig, 
    TriviaConfig as TriviaConfigDB, 
    ModerationConfig 
} from "@db/schema/game-settings";
import type { GuildConfig } from "@db/schema/guild-settings";

const guildConfigCache = new Map<string, { config: GuildConfig; timestamp: number }>();
const CACHE_TTL_MS = 60000;

export async function getGuildConfig(guildId: string): Promise<GuildConfig> {
    const cached = guildConfigCache.get(guildId);
    if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
        return cached.config;
    }

    try {
        const { guildSettingsService } = await import('@shared/modules/guild-settings/guild-settings.service');
        const dbSettings = await guildSettingsService.getSettings(guildId);

        if (dbSettings) {
            const config: GuildConfig = {
                studentRole: dbSettings.studentRoleId,
                visitorRole: dbSettings.visitorRoleId,
                colorRoles: dbSettings.colorRoleIds ?? [],
                welcomeChannelId: dbSettings.welcomeChannelId,
                welcomeMessage: dbSettings.welcomeMessage,
                feedbackChannelId: dbSettings.feedbackChannelId,
                terminal: dbSettings.terminalChannelId ? {
                    channelId: dbSettings.terminalChannelId,
                    messageId: dbSettings.terminalMessageId ?? "",
                } : undefined,
                moderation: {
                    cases: {
                        dmOnWarn: dbSettings.moderationDmOnWarn ?? true,
                        logChannelId: dbSettings.moderationLogChannelId,
                        autoTimeoutThreshold: dbSettings.moderationAutoTimeoutThreshold,
                    },
                },
            };

            guildConfigCache.set(guildId, { config, timestamp: Date.now() });
            return config;
        }
    } catch (error) {
        console.error("Failed to load guild config from database:", error);
    }

    return {
        studentRole: undefined,
        visitorRole: undefined,
        colorRoles: [],
        welcomeChannelId: undefined,
        welcomeMessage: undefined,
        feedbackChannelId: undefined,
        terminal: undefined,
        moderation: { cases: { dmOnWarn: true } },
    };
}

export function invalidateGuildConfigCache(guildId: string) {
    guildConfigCache.delete(guildId);
}

// Re-export DB types
export type { LevelingConfig, LootdropConfig, ModerationConfig };

// Runtime config types with BigInt for numeric fields
export interface EconomyConfig {
    daily: {
        amount: bigint;
        streakBonus: bigint;
        weeklyBonus: bigint;
        cooldownMs: number;
    };
    transfers: {
        allowSelfTransfer: boolean;
        minAmount: bigint;
    };
    exam: {
        multMin: number;
        multMax: number;
    };
}

export interface InventoryConfig {
    maxStackSize: bigint;
    maxSlots: number;
}

export interface TriviaConfig {
    entryFee: bigint;
    rewardMultiplier: number;
    timeoutSeconds: number;
    cooldownMs: number;
    categories: number[];
    difficulty: 'easy' | 'medium' | 'hard' | 'random';
}

export interface GameConfigType {
    leveling: LevelingConfig;
    economy: EconomyConfig;
    inventory: InventoryConfig;
    commands: Record<string, boolean>;
    lootdrop: LootdropConfig;
    trivia: TriviaConfig;
    moderation: ModerationConfig;
    system: Record<string, unknown>;
}

export const config: GameConfigType = {} as GameConfigType;

export const GameConfig = config;

async function loadFromDatabase(): Promise<boolean> {
    try {
        const { gameSettingsService } = await import('@shared/modules/game-settings/game-settings.service');
        const dbSettings = await gameSettingsService.getSettings();

        if (dbSettings) {
            Object.assign(config, {
                leveling: {
                    ...dbSettings.leveling,
                },
                economy: {
                    daily: {
                        ...dbSettings.economy.daily,
                        amount: BigInt(dbSettings.economy.daily.amount),
                        streakBonus: BigInt(dbSettings.economy.daily.streakBonus),
                        weeklyBonus: BigInt(dbSettings.economy.daily.weeklyBonus),
                    },
                    transfers: {
                        ...dbSettings.economy.transfers,
                        minAmount: BigInt(dbSettings.economy.transfers.minAmount),
                    },
                    exam: dbSettings.economy.exam,
                },
                inventory: {
                    ...dbSettings.inventory,
                    maxStackSize: BigInt(dbSettings.inventory.maxStackSize),
                },
                commands: dbSettings.commands,
                lootdrop: dbSettings.lootdrop,
                trivia: {
                    ...dbSettings.trivia,
                    entryFee: BigInt(dbSettings.trivia.entryFee),
                },
                moderation: dbSettings.moderation,
                system: dbSettings.system,
            });
            console.log("🎮 Game config loaded from database.");
            return true;
        }
    } catch (error) {
        console.error("Failed to load game config from database:", error);
    }
    return false;
}

async function loadDefaults(): Promise<void> {
    console.warn("⚠️ No game config found in database. Using defaults.");
    const { gameSettingsService } = await import('@shared/modules/game-settings/game-settings.service');
    const defaults = gameSettingsService.getDefaults();
    Object.assign(config, {
        leveling: defaults.leveling,
        economy: {
            ...defaults.economy,
            daily: {
                ...defaults.economy.daily,
                amount: BigInt(defaults.economy.daily.amount),
                streakBonus: BigInt(defaults.economy.daily.streakBonus),
                weeklyBonus: BigInt(defaults.economy.daily.weeklyBonus),
            },
            transfers: {
                ...defaults.economy.transfers,
                minAmount: BigInt(defaults.economy.transfers.minAmount),
            },
        },
        inventory: {
            ...defaults.inventory,
            maxStackSize: BigInt(defaults.inventory.maxStackSize),
        },
        commands: defaults.commands,
        lootdrop: defaults.lootdrop,
        trivia: {
            ...defaults.trivia,
            entryFee: BigInt(defaults.trivia.entryFee),
        },
        moderation: defaults.moderation,
        system: defaults.system,
    });
}

export async function reloadConfig(): Promise<void> {
    const dbLoaded = await loadFromDatabase();
    
    if (!dbLoaded) {
        await loadDefaults();
    }
}

export async function initializeConfig(): Promise<void> {
    await reloadConfig();
}
