import { sessionId, currentPersona, setCurrentPersona, dom } from './state.js';
import { GENRE_LABELS, bindGenreGrid, resetGenreGrid } from './utils.js';
import { personaIndex } from './personas.js';

const chatSettingsGenres = new Set();
let chatSettingsPersonaId = 'default';
let chatSettingsInitialPersonaId = 'default';

function updateChatSettingsGenresLabel() {
    const el = document.getElementById('chatSettingsGenresLabel');
    const labels = [...chatSettingsGenres].map(g => GENRE_LABELS[g] || g);
    if (!el) return;
    if (labels.length) {
        el.textContent = `Выбрано: ${labels.join(' + ')}`;
        el.classList.remove('hidden');
    } else {
        el.classList.add('hidden');
    }
}

function fillChatSettingsPersonaGrid() {
    const grid = document.getElementById('chatSettingsPersonaGrid');
    if (!grid) return;
    grid.innerHTML = '';
    for (const p of personaIndex.values()) {
        const card = document.createElement('button');
        card.type = 'button';
        card.className = 'persona-pick-card' + (p.persona_id === chatSettingsPersonaId ? ' selected' : '');
        card.dataset.id = p.persona_id;
        card.innerHTML = `<span class="emoji">${p.emoji || '🤖'}</span>${p.name}`;
        card.addEventListener('click', () => {
            chatSettingsPersonaId = p.persona_id;
            grid.querySelectorAll('.persona-pick-card').forEach(c => {
                c.classList.toggle('selected', c.dataset.id === chatSettingsPersonaId);
            });
        });
        grid.appendChild(card);
    }
}

function loadRpgSettingsToDom(prefix, settings) {
    document.getElementById(`${prefix}SettingDice`).checked = settings.dice !== false;
    document.getElementById(`${prefix}SettingNarrator`).checked = settings.narrator !== false;
    document.getElementById(`${prefix}SettingQuests`).checked = settings.quests !== false;
    document.getElementById(`${prefix}SettingAffinity`).checked = settings.affinity !== false;
    document.getElementById(`${prefix}SettingStats`).checked = settings.stats === true;
    document.getElementById(`${prefix}SettingChoices`).checked = settings.choices !== false;
}

function readRpgSettingsFromDom(prefix) {
    return {
        dice: document.getElementById(`${prefix}SettingDice`)?.checked ?? true,
        narrator: document.getElementById(`${prefix}SettingNarrator`)?.checked ?? true,
        quests: document.getElementById(`${prefix}SettingQuests`)?.checked ?? true,
        affinity: document.getElementById(`${prefix}SettingAffinity`)?.checked ?? true,
        stats: document.getElementById(`${prefix}SettingStats`)?.checked ?? false,
        choices: document.getElementById(`${prefix}SettingChoices`)?.checked ?? true,
    };
}

async function bootstrapRpg(sid, personaId, genreValue, settings) {
    const { updateQuestPanel, addMessage } = await import('./chat.js');
    await fetch(`/sessions/${sid}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            rpg_enabled: true,
            genre: genreValue,
            rpg_settings_json: JSON.stringify(settings),
        }),
    });
    const res = await fetch('/chat/rpg/bootstrap', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ session_id: sid, persona_id: personaId, genre: genreValue }),
    });
    if (res.ok) {
        const data = await res.json();
        if (data.affinity !== undefined) {
            const { updateAffinityDisplay } = await import('./chat.js');
            updateAffinityDisplay(data.affinity);
        }
        if (data.quests) updateQuestPanel(data.quests, data.plot_arc ?? null);
        if (data.plot_arc) {
            const title = data.plot_arc.title || '';
            const hint = data.plot_arc.next_beat_hint || '';
            if (title || hint) addMessage('assistant', `📖 ${title}${hint ? '\n' + hint : ''}`);
        }
    }
}

export async function openChatSettings() {
    if (!sessionId) return;
    const res = await fetch(`/sessions/${sessionId}`);
    if (!res.ok) return;
    const s = await res.json();

    document.getElementById('chatSettingsTitle').value = s.title || '';
    chatSettingsPersonaId = s.persona_id || 'default';
    chatSettingsInitialPersonaId = chatSettingsPersonaId;
    fillChatSettingsPersonaGrid();

    const rpgOn = !!s.rpg_enabled;
    document.getElementById('chatSettingsRpg').checked = rpgOn;
    document.getElementById('chatSettingsRpgBlock').classList.toggle('hidden', !rpgOn);

    chatSettingsGenres.clear();
    (s.genre || 'adventure').split(',').forEach(g => {
        const t = g.trim();
        if (t) chatSettingsGenres.add(t);
    });
    resetGenreGrid(document.getElementById('chatSettingsGenreGrid'), chatSettingsGenres);
    document.getElementById('chatSettingsGenreGrid')?.querySelectorAll('.genre-btn').forEach(btn => {
        if (chatSettingsGenres.has(btn.dataset.genre)) btn.classList.add('selected');
    });
    updateChatSettingsGenresLabel();

    let settings = {};
    try { settings = JSON.parse(s.rpg_settings_json || '{}'); } catch { /* ignore */ }
    loadRpgSettingsToDom('cs', settings);

    let phase = '';
    try {
        const arc = JSON.parse(s.plot_arc_json || '{}');
        phase = arc.phase || '';
    } catch { /* ignore */ }
    let stats = { lust: 0, stamina: 10, tension: 0 };
    try {
        stats = { ...stats, ...JSON.parse(s.narrative_stats_json || '{}') };
    } catch { /* ignore */ }

    document.getElementById('chatSettingsMeta').innerHTML = [
        `Симпатия: ${s.affinity ?? 0}`,
        settings.stats
            ? `Шкалы: lust ${stats.lust ?? 0}, stamina ${stats.stamina ?? 10}, tension ${stats.tension ?? 0}`
            : '',
        s.genre ? `Жанр: ${(s.genre || '').split(',').map(g => GENRE_LABELS[g.trim()] || g).join(' + ')}` : '',
        phase ? `Фаза арки: ${phase}` : '',
    ].filter(Boolean).join('<br>');

    const dbg = document.getElementById('chatSettingsRpgDebug');
    if (dbg) dbg.open = rpgOn;
    const affIn = document.getElementById('debugAffinity');
    const lustIn = document.getElementById('debugLust');
    const stamIn = document.getElementById('debugStamina');
    const tensIn = document.getElementById('debugTension');
    if (affIn) affIn.value = String(s.affinity ?? 0);
    if (lustIn) lustIn.value = String(stats.lust ?? 0);
    if (stamIn) stamIn.value = String(stats.stamina ?? 10);
    if (tensIn) tensIn.value = String(stats.tension ?? 0);
    const st = document.getElementById('debugRpgStateStatus');
    if (st) st.textContent = '';

    document.getElementById('chatSettingsModal').classList.add('open');
}

export function initChatSettings() {
    bindGenreGrid(
        document.getElementById('chatSettingsGenreGrid'),
        chatSettingsGenres,
        updateChatSettingsGenresLabel,
    );

    document.getElementById('chatSettingsRpg')?.addEventListener('change', (e) => {
        document.getElementById('chatSettingsRpgBlock').classList.toggle('hidden', !e.target.checked);
    });

    document.getElementById('chatSettingsCancel')?.addEventListener('click', () => {
        document.getElementById('chatSettingsModal').classList.remove('open');
    });

    document.getElementById('debugRpgStateApply')?.addEventListener('click', async () => {
        if (!sessionId) return;
        const statusEl = document.getElementById('debugRpgStateStatus');
        const body = {};
        const aff = document.getElementById('debugAffinity')?.value;
        const lust = document.getElementById('debugLust')?.value;
        const stam = document.getElementById('debugStamina')?.value;
        const tens = document.getElementById('debugTension')?.value;
        if (aff !== '' && aff != null) body.affinity = Number(aff);
        if (lust !== '' && lust != null) body.lust = Number(lust);
        if (stam !== '' && stam != null) body.stamina = Number(stam);
        if (tens !== '' && tens != null) body.tension = Number(tens);
        try {
            const res = await fetch(`/sessions/${sessionId}/rpg-state`, {
                method: 'PATCH',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(body),
            });
            if (!res.ok) {
                const err = await res.json().catch(() => ({}));
                if (statusEl) {
                    statusEl.textContent = err.detail || 'Ошибка';
                    statusEl.style.color = '#e74c3c';
                }
                return;
            }
            const data = await res.json();
            const { updateAffinityDisplay, updateStatsDisplay } = await import('./chat.js');
            if (data.affinity !== undefined) updateAffinityDisplay(data.affinity);
            if (data.narrative_stats) updateStatsDisplay(data.narrative_stats);
            if (statusEl) {
                statusEl.textContent = 'Сохранено';
                statusEl.style.color = '#2ecc71';
            }
            const blobRes = await fetch(`/chat/system/${sessionId}`);
            if (blobRes.ok) {
                const { renderSystemBlob } = await import('./sessions.js');
                renderSystemBlob(await blobRes.json());
            }
        } catch {
            if (statusEl) {
                statusEl.textContent = 'Сеть';
                statusEl.style.color = '#e74c3c';
            }
        }
    });

    document.getElementById('chatSettingsSave')?.addEventListener('click', async () => {
        if (!sessionId) return;
        const { loadSessions, applySessionUi, renderSystemBlob } = await import('./sessions.js');
        const { reloadChatFromServer } = await import('./chat.js');
        const { highlightPersonaBar } = await import('./personas.js');

        const title = document.getElementById('chatSettingsTitle').value.trim();
        const rpgOn = document.getElementById('chatSettingsRpg').checked;
        const genreValue = [...chatSettingsGenres].join(',') || 'adventure';
        const settings = readRpgSettingsFromDom('cs');

        if (chatSettingsPersonaId !== chatSettingsInitialPersonaId) {
            const pName = personaIndex.get(chatSettingsPersonaId)?.name || chatSettingsPersonaId;
            const keepHistory = confirm(
                `Перепривязать чат к «${pName}»?\n\n`
                + 'OK — сохранить историю сообщений (персонаж в старых репликах может не совпадать).\n'
                + 'Отмена — очистить историю и начать с приветствия нового персонажа.',
            );
            const clearHistory = !keepHistory;

            const rebindRes = await fetch(`/sessions/${sessionId}/rebind-persona`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    persona_id: chatSettingsPersonaId,
                    clear_history: clearHistory,
                }),
            });
            if (!rebindRes.ok) {
                const err = await rebindRes.json().catch(() => ({}));
                alert(err.detail || 'Не удалось сменить персонажа');
                return;
            }
            setCurrentPersona(chatSettingsPersonaId);
            chatSettingsInitialPersonaId = chatSettingsPersonaId;
            highlightPersonaBar(chatSettingsPersonaId);
            await reloadChatFromServer(sessionId);
            const blobRes = await fetch(`/chat/system/${sessionId}`);
            if (blobRes.ok) renderSystemBlob(await blobRes.json());
        }

        await fetch(`/sessions/${sessionId}`, {
            method: 'PATCH',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                title: title || undefined,
                rpg_enabled: rpgOn,
                genre: genreValue,
                rpg_settings_json: JSON.stringify(settings),
            }),
        });

        if (rpgOn) {
            const sessionRes = await fetch(`/sessions/${sessionId}`);
            const s = sessionRes.ok ? await sessionRes.json() : {};
            let arc = {};
            try { arc = JSON.parse(s.plot_arc_json || '{}'); } catch { /* ignore */ }
            if (!arc || !Object.keys(arc).length) {
                await bootstrapRpg(sessionId, chatSettingsPersonaId, genreValue, settings);
            }
        }

        document.getElementById('chatSettingsModal').classList.remove('open');
        const updated = await (await fetch(`/sessions/${sessionId}`)).json();
        applySessionUi(updated);
        dom.headerTitle.textContent = updated.title || 'Новый чат';
        await loadSessions();
    });
}
