/**
 * InnRoller
 * Classe de gestion des jets de tables d'auberge pour WFRP4e
 * Module de traduction française
 */

export default class InnRoller {
    static tableNames = {
        'boissonsbase': 'BoissonsBase',
        'boissonsfortes': 'BoissonsFortes',
        'desserts': 'Desserts',
        'platscommuns': 'PlatsCommuns',
        'platsexcellents': 'PlatsExcellents',
        'platsmaritimes': 'PlatsMaritimes',
        'platsmediocres': 'PlatsMédiocres',
        'platsqualite': 'PlatsQualité',
        'platsrivieres': 'PlatsRivières'
    };

    static displayNames = {
        'BoissonsBase': 'Boissons de Base',
        'BoissonsFortes': 'Boissons Fortes',
        'Desserts': 'Desserts',
        'PlatsCommuns': 'Plats Communs',
        'PlatsExcellents': 'Plats Excellents',
        'PlatsMaritimes': 'Plats Maritimes',
        'PlatsMédiocres': 'Plats Médiocres',
        'PlatsQualité': 'Plats de Qualité',
        'PlatsRivières': 'Plats de Rivières'
    };

    /**
     * Obtient le nom d'affichage formaté pour une table
     * @param {String} tableName
     * @returns {String}
     */
    static getDisplayName(tableName) {
        return this.displayNames[tableName] || tableName;
    }

    /**
     * Normalise le nom d'une table (enlève accents, espaces, met en minuscules)
     * @param {String} name
     * @returns {String}
     */
    static normalizeTableName(name) {
        return name
            .toLowerCase()
            .normalize("NFD")
            .replace(/[\u0300-\u036f]/g, "")
            .replace(/\s+/g, '');
    }

    /**
     * Trouve la table correspondant au mot-clé
     * @param {String} keyword
     * @returns {String|null}
     */
    static findTableByKeyword(keyword) {
        if (!keyword) return null;

        const normalized = this.normalizeTableName(keyword);

        // Recherche exacte
        if (this.tableNames[normalized]) {
            return this.tableNames[normalized];
        }

        // Recherche partielle
        for (let [key, value] of Object.entries(this.tableNames)) {
            if (key.includes(normalized) || normalized.includes(key)) {
                return value;
            }
        }

        return null;
    }

    /**
     * Lance un jet sur une table d'auberge
     * @param {String} keyword Mot-clé pour identifier la table
     */
    static async rollInnTable(keyword) {
        console.log(`InnRoller: rollInnTable appelé avec keyword="${keyword}"`);

        // Si pas de keyword, afficher l'aide
        if (!keyword) {
            this.displayHelp();
            return;
        }

        // Rechercher la table
        const tableName = this.findTableByKeyword(keyword);

        if (!tableName) {
            this.displayHelp();
            ui.notifications.warn(`Table d'auberge introuvable pour le mot-clé: "${keyword}"`);
            return;
        }

        console.log(`InnRoller: Table trouvée: ${tableName}`);

        // Charger le compendium
        const compendium = game.packs.get('wh4-fr-translation.plats-dauberges');

        if (!compendium) {
            ui.notifications.error("Compendium 'plats-dauberges' introuvable");
            console.error("InnRoller: Compendium wh4-fr-translation.plats-dauberges non trouvé");
            return;
        }

        // Récupérer les tables
        const tables = await compendium.getDocuments();

        // Trouver la table correspondante
        const rollTable = tables.find(t => t.name === tableName);

        if (!rollTable) {
            ui.notifications.error(`Table "${tableName}" non trouvée dans le compendium`);
            console.error(`InnRoller: Table ${tableName} non trouvée`);
            return;
        }

        console.log(`InnRoller: Jet sur la table ${rollTable.name}`);

        // Effectuer le jet sans affichage automatique
        try {
            const roll = await rollTable.draw({ displayChat: false });
            console.log(`InnRoller: Jet effectué avec succès`, roll);

            // Créer un message personnalisé
            await this.displayRollResult(rollTable.name, roll);
        } catch (error) {
            console.error("InnRoller: Erreur lors du jet:", error);
            ui.notifications.error("Erreur lors du jet sur la table d'auberge");
        }
    }

    /**
     * Affiche le résultat d'un jet de table avec un style personnalisé
     * @param {String} tableName Nom de la table
     * @param {Object} rollResult Résultat du jet
     */
    static async displayRollResult(tableName, rollResult) {
        // Déterminer l'icône en fonction du type de table
        let icon = "fa-utensils";
        let category = "Plat";

        if (tableName.toLowerCase().includes('boisson')) {
            icon = "fa-wine-glass";
            category = "Boisson";
        } else if (tableName.toLowerCase().includes('dessert')) {
            icon = "fa-birthday-cake";
            category = "Dessert";
        }

        // Extraire les informations du résultat
        const resultText = rollResult.results[0]?.name || rollResult.results[0]?.description || "Résultat inconnu";
        const rollFormula = rollResult.roll?.formula || "1d100";
        const rollTotal = rollResult.roll?.total || 0;

        // Construire le message HTML simplifié
        let message = `<div class="wfrp4e-inn-result">`;
        message += `<div class="message-header">`;
        message += `<i class="fas ${icon}"></i> `;
        message += `<span class="flavor-text">${category}: ${tableName}</span>`;
        message += `</div>`;
        message += `<div class="inn-dish-name">${resultText}</div>`;
        message += `<div class="inn-roll-info"><i class="fas fa-dice"></i> ${rollFormula} = ${rollTotal}</div>`;
        message += `</div>`;

        // Créer le message dans le chat
        await ChatMessage.create({
            content: message,
            speaker: ChatMessage.getSpeaker(),
            whisper: ChatMessage.getWhisperRecipients("GM")
        });
    }

    /**
     * Affiche l'aide pour la commande /auberge avec liste cliquable
     */
    static displayHelp() {
        let message = `<div class="wfrp4e-inn-help">`;
        message += `<h3><i class="fas fa-utensils"></i> Aide pour /auberge</h3>`;
        message += `<p><strong>Usage:</strong> <code>/auberge [mot_clé]</code></p>`;

        // Bouton Menu
        message += `<div style="margin: 0.8em 0;">`;
        message += `<a class="action-link inn-menu-quick-btn" data-action="clickAubergeMenu" data-quality="menu">`;
        message += `<i class="fas fa-book-open"></i> Générer un menu complet`;
        message += `</a>`;
        message += `</div>`;

        message += `<hr>`;

        // Section avec liste cliquable
        message += `<h4><i class="fas fa-list"></i> Tables disponibles</h4>`;
        message += `<div class="wfrp4e-inn-table-grid">`;

        const sortedTables = Object.values(this.tableNames).sort();
        for (let tableName of sortedTables) {
            const normalized = this.normalizeTableName(tableName);
            const displayName = this.getDisplayName(tableName);
            message += `<a class="action-link inn-table-btn" data-action="clickAuberge" data-table="${normalized}">`;
            message += `<i class="fas fa-dice"></i> ${displayName}`;
            message += `</a>`;
        }

        message += `</div>`;
        message += `<hr>`;
        message += `<p style="font-size: 0.9em; margin-top: 0.5em;"><em>Vous pouvez aussi taper <code>/auberge [mot_clé]</code> directement (ex: <code>/auberge base</code>)</em></p>`;
        message += `</div>`;

        ChatMessage.create({
            content: message,
            whisper: ChatMessage.getWhisperRecipients("GM")
        });
    }

    /**
     * Liste toutes les tables disponibles
     */
    static listTables() {
        let message = `<div class="wfrp4e-inn-list">`;
        message += `<h3><i class="fas fa-list"></i> Tables d'auberge disponibles</h3>`;
        message += `<div class="wfrp4e-inn-table-grid">`;

        const sortedTables = Object.values(this.tableNames).sort();
        for (let tableName of sortedTables) {
            const normalized = this.normalizeTableName(tableName);
            const displayName = this.getDisplayName(tableName);
            message += `<a class="action-link inn-table-btn" data-action="clickAuberge" data-table="${normalized}">`;
            message += `<i class="fas fa-dice"></i> ${displayName}`;
            message += `</a>`;
        }

        message += `</div>`;
        message += `</div>`;

        ChatMessage.create({
            content: message,
            whisper: ChatMessage.getWhisperRecipients("GM")
        });
    }

    /**
     * Affiche le choix de qualité pour générer un menu complet
     */
    static displayMenuChoice() {
        let message = `<div class="wfrp4e-inn-menu-choice">`;
        message += `<h3><i class="fas fa-book-open"></i> Menu de l'auberge</h3>`;
        message += `<p>Choisissez la qualité du menu :</p>`;
        message += `<div class="inn-menu-buttons">`;

        message += `<a class="action-link inn-menu-btn" data-action="clickAubergeMenu" data-quality="mediocre">`;
        message += `<i class="fas fa-drumstick-bite"></i> Menu Médiocre`;
        message += `<br><span class="inn-menu-desc">Plat médiocre + Boisson de base</span>`;
        message += `</a>`;

        message += `<a class="action-link inn-menu-btn" data-action="clickAubergeMenu" data-quality="commun">`;
        message += `<i class="fas fa-utensils"></i> Menu Commun`;
        message += `<br><span class="inn-menu-desc">Plat commun + Boisson de base + Dessert</span>`;
        message += `</a>`;

        message += `<a class="action-link inn-menu-btn" data-action="clickAubergeMenu" data-quality="qualite">`;
        message += `<i class="fas fa-crown"></i> Menu de Qualité`;
        message += `<br><span class="inn-menu-desc">Plat de qualité + Boisson forte + Dessert</span>`;
        message += `</a>`;

        message += `<a class="action-link inn-menu-btn" data-action="clickAubergeMenu" data-quality="fluvial">`;
        message += `<i class="fas fa-fish"></i> Menu Fluvial`;
        message += `<br><span class="inn-menu-desc">Plat de rivière + Boisson de base + Dessert</span>`;
        message += `</a>`;

        message += `<a class="action-link inn-menu-btn" data-action="clickAubergeMenu" data-quality="maritime">`;
        message += `<i class="fas fa-anchor"></i> Menu Maritime`;
        message += `<br><span class="inn-menu-desc">Plat maritime + Boisson forte + Dessert</span>`;
        message += `</a>`;

        message += `<a class="action-link inn-menu-btn" data-action="clickAubergeMenu" data-quality="excellent">`;
        message += `<i class="fas fa-gem"></i> Menu Excellent`;
        message += `<br><span class="inn-menu-desc">Plat excellent + Boisson forte + Dessert</span>`;
        message += `</a>`;

        message += `</div>`;
        message += `</div>`;

        ChatMessage.create({
            content: message,
            whisper: ChatMessage.getWhisperRecipients("GM")
        });
    }

    /**
     * Génère un menu complet selon la qualité choisie
     * @param {String} quality - 'mediocre', 'commun', ou 'qualite'
     */
    static async generateMenu(quality) {
        console.log(`InnRoller: generateMenu appelé avec quality="${quality}"`);

        let tables = [];
        let menuName = "";

        // Définir les tables à tirer selon la qualité
        switch(quality) {
            case 'mediocre':
                menuName = "Menu Médiocre";
                tables = ['PlatsMédiocres', 'BoissonsBase'];
                break;
            case 'commun':
                menuName = "Menu Commun";
                tables = ['PlatsCommuns', 'BoissonsBase', 'Desserts'];
                break;
            case 'qualite':
                menuName = "Menu de Qualité";
                tables = ['PlatsQualité', 'BoissonsFortes', 'Desserts'];
                break;
            case 'fluvial':
                menuName = "Menu Fluvial";
                tables = ['PlatsRivières', 'BoissonsBase', 'Desserts'];
                break;
            case 'maritime':
                menuName = "Menu Maritime";
                tables = ['PlatsMaritimes', 'BoissonsFortes', 'Desserts'];
                break;
            case 'excellent':
                menuName = "Menu Excellent";
                tables = ['PlatsExcellents', 'BoissonsFortes', 'Desserts'];
                break;
            default:
                ui.notifications.error(`Qualité de menu inconnue: ${quality}`);
                return;
        }

        // Charger le compendium
        const compendium = game.packs.get('wh4-fr-translation.plats-dauberges');
        if (!compendium) {
            ui.notifications.error("Compendium 'plats-dauberges' introuvable");
            return;
        }

        const allTables = await compendium.getDocuments();
        let results = [];

        // Effectuer les jets sur chaque table
        for (let tableName of tables) {
            const rollTable = allTables.find(t => t.name === tableName);
            if (rollTable) {
                try {
                    const roll = await rollTable.draw({ displayChat: false });
                    const resultText = roll.results[0]?.name || roll.results[0]?.description || "Résultat inconnu";
                    results.push({
                        category: this.getCategoryName(tableName),
                        name: resultText,
                        tableName: tableName
                    });
                } catch (error) {
                    console.error(`InnRoller: Erreur lors du jet sur ${tableName}:`, error);
                }
            }
        }

        // Afficher le menu complet
        this.displayMenuResult(menuName, results);
    }

    /**
     * Obtient le nom de catégorie pour une table
     * @param {String} tableName
     * @returns {String}
     */
    static getCategoryName(tableName) {
        if (tableName.includes('Boisson')) return 'Boisson';
        if (tableName.includes('Dessert')) return 'Dessert';
        if (tableName.includes('Plat')) return 'Plat';
        return 'Item';
    }

    /**
     * Affiche le résultat d'un menu complet
     * @param {String} menuName
     * @param {Array} results
     */
    static async displayMenuResult(menuName, results) {
        let message = `<div class="wfrp4e-inn-menu-result">`;
        message += `<div class="message-header">`;
        message += `<i class="fas fa-book-open"></i> `;
        message += `<span class="flavor-text">${menuName}</span>`;
        message += `</div>`;

        message += `<div class="inn-menu-items">`;
        for (let result of results) {
            message += `<div class="inn-menu-item">`;
            let icon = result.category === 'Boisson' ? 'fa-wine-glass' :
                      result.category === 'Dessert' ? 'fa-birthday-cake' : 'fa-utensils';
            message += `<i class="fas ${icon}"></i> `;
            message += `<strong>${result.category}:</strong> ${result.name}`;
            message += `</div>`;
        }
        message += `</div>`;

        // Bouton pour enregistrer dans le journal "Menus"
        message += `<div class="inn-journal-action" style="margin-top:8px;text-align:right">`;
        message += `<button type="button" class="inn-journal-btn" data-action="saveMenuToJournal"`;
        message += ` data-menu-name="${menuName}">`;
        message += `<i class="fas fa-book"></i> Enregistrer dans le journal "Menus"`;
        message += `</button>`;
        message += `</div>`;

        message += `</div>`;

        await ChatMessage.create({
            content: message,
            speaker: ChatMessage.getSpeaker(),
            whisper: ChatMessage.getWhisperRecipients("GM")
        });
    }

    /**
     * Enregistre le contenu d'un menu dans le journal FoundryVTT "Menus"
     * @param {String} menuName - Nom du menu (ex: "Menu Commun")
     * @param {String} content - HTML complet du message de tchat
     */
    static async saveMenuToJournal(menuName, content) {
        if (!game.user.isGM) {
            ui.notifications.warn("Seul le MJ peut enregistrer dans le journal.");
            return;
        }

        const journalName = "Menus";
        let journal = game.journal.find(j => j.name === journalName);
        if (!journal) {
            journal = await JournalEntry.create({ name: journalName });
        }

        // Supprimer le bouton du contenu avant de l'enregistrer
        const parser = new DOMParser();
        const doc = parser.parseFromString(content, 'text/html');
        doc.querySelectorAll('.inn-journal-action').forEach(el => el.remove());
        const cleanContent = doc.body.innerHTML;

        const now = new Date();
        const dateStr = now.toLocaleDateString('fr-FR');
        const pageName = `${menuName} (${dateStr})`;

        await journal.createEmbeddedDocuments("JournalEntryPage", [{
            name: pageName,
            type: "text",
            text: {
                content: cleanContent,
                format: CONST.JOURNAL_ENTRY_PAGE_FORMATS.HTML
            }
        }]);

        // Ouvrir le journal sur la nouvelle page
        const page = journal.pages.find(p => p.name === pageName);
        journal.sheet.render(true, { pageId: page?.id });
        ui.notifications.info(`Menu "${menuName}" enregistré dans le journal.`);
    }
}
