/**
 * qix_ui.js
 * UI管理クラス (難易度表示レイアウト修正版 v2)
 */
class UIManager {
    constructor(gameInstance) {
        this.game = gameInstance;
        this.menuOverlay = document.getElementById('menu-overlay');
        this.stageGrid = document.getElementById('stage-grid');
        this.gameoverOverlay = document.getElementById('gameover-overlay');
        
        document.getElementById('btn-retry').onclick = () => {
            this.hideGameOver();
            this.game.loadStage(this.game.stageIndex);
        };
        document.getElementById('btn-menu').onclick = () => {
            this.hideGameOver();
            this.game.returnToMenu();
        };
    }

    showStageSelect() {
        this.hideAll();
        this.menuOverlay.style.display = 'flex';

        const grid = this.stageGrid;
        grid.innerHTML = '';

        this._stageCards = [];
        this._stageCols = 3;
        this._stageFocus = 0;
        const _lastStageIndex = (this.game.stageIndex != null) ? this.game.stageIndex : -1;

        grid.classList.add('free-grid');
        document.getElementById('menu-title').innerText = "SELECT STAGE";

        const stageList = STAGE_DATA.FREE;
        let shownMyStages = false;

        stageList.forEach((stage, index) => {
            if (stage.id >= 101 && !shownMyStages) {
                shownMyStages = true;
                const sep = document.createElement('div');
                sep.className = 'episode-header';
                sep.innerText = '── MY STAGES ──';
                grid.appendChild(sep);
            }

            const btn = document.createElement('div');
            const isCleared = this.game.achievements && this.game.achievements.stats.stagesCleared.has(stage.id);
            btn.className = 'stage-card' + (isCleared ? ' cleared' : '');

            if (stage.assets && stage.assets.hidden) {
                btn.style.backgroundImage = `linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(0,0,0,0.8)), url(${stage.assets.hidden})`;
            }

            const title = document.createElement('div');
            title.className = 'stage-title';
            title.innerText = `STAGE ${String(stage.id).padStart(2, '0')}`;

            const info = document.createElement('div');
            info.className = 'stage-info';

            const diff = stage.difficulty || 1;
            const maxDiff = Math.max(1, ...STAGE_DATA.FREE.map(s => s.difficulty || 1));
            const stars = Math.max(1, Math.min(13, Math.ceil(diff * 13 / maxDiff)));
            let starsHtml = '';
            if (stars <= 7) {
                starsHtml = '★'.repeat(stars);
            } else {
                starsHtml = '★'.repeat(7) + '<br><span style="display:inline-block; margin-left: 0.6em;">' + '★'.repeat(stars - 7) + '</span>';
            }

            const best = this.game.achievements && this.game.achievements.stats.bestErosion[stage.id];
            const bestHtml = best
                ? `<br><span style="color:#BC13FE;font-size:0.85em;letter-spacing:1px;">BEST: ${(best*100).toFixed(1)}%</span>`
                : '';
            const stageName = stage.name || stage._stageName || '';
            const stageNameHtml = stageName ? `「${stageName}」` : '';
            info.innerHTML = `<span style="font-size:0.9em;letter-spacing:1px;opacity:0.9;">${stageNameHtml}</span><br>
                <span style="color: #FFD700; font-size: 1.2em; letter-spacing: 2px; line-height: 1.0; display:inline-block;">
                    ${starsHtml}
                </span>${bestHtml}`;

            btn.appendChild(title);
            btn.appendChild(info);

            const cardIndex = this._stageCards.length;
            btn.onclick = () => {
                this._stageFocus = cardIndex;
                this._selectFocusedStage(stageList);
            };

            this._stageCards.push({ el: btn, stageIndex: index });
            this.stageGrid.appendChild(btn);
        });

        if (_lastStageIndex >= 0) {
            const match = this._stageCards.findIndex(c => c.stageIndex === _lastStageIndex);
            if (match >= 0) this._stageFocus = match;
        }
        this._updateStageFocus();
    }

    _updateStageFocus() {
        const cards = this._stageCards;
        if (!cards || cards.length === 0) return;
        cards.forEach((c, i) => c.el.classList.toggle('focused', i === this._stageFocus));
        cards[this._stageFocus].el.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
    }

    _selectFocusedStage(stageList) {
        if (!this._stageCards || this._stageCards.length === 0) return;
        const card = this._stageCards[this._stageFocus];
        this.hideAll();
        this.game.currentStageList = stageList || STAGE_DATA.FREE;
        this.game.loadStage(card.stageIndex);
    }

    stageSelectKey(key) {
        const cards = this._stageCards;
        if (!cards || cards.length === 0) return;
        const cols = this._stageCols;
        const n = cards.length;
        let f = this._stageFocus;

        if (key === 'ArrowRight') f = Math.min(f + 1, n - 1);
        else if (key === 'ArrowLeft') f = Math.max(f - 1, 0);
        else if (key === 'ArrowDown') f = Math.min(f + cols, n - 1);
        else if (key === 'ArrowUp') f = Math.max(f - cols, 0);
        else if (key === 'Enter' || key === 'z' || key === 'Z') {
            this._selectFocusedStage();
            return;
        } else if (key === 'Escape' || key === 'Backspace') {
            this.game.returnToTitle();
            return;
        }

        this._stageFocus = f;
        this._updateStageFocus();
    }

    showGameOver() {
        this.gameoverOverlay.style.display = 'flex';
        this._goFocus = 0;
        this._updateGameOverFocus();
    }

    hideGameOver() {
        this.gameoverOverlay.style.display = 'none';
    }

    _updateGameOverFocus() {
        document.getElementById('btn-retry').classList.toggle('focused', this._goFocus === 0);
        document.getElementById('btn-menu').classList.toggle('focused', this._goFocus === 1);
    }

    gameOverKey(key) {
        if (key === 'ArrowLeft' || key === 'ArrowRight') {
            this._goFocus = this._goFocus === 0 ? 1 : 0;
            this._updateGameOverFocus();
        } else if (key === 'Enter' || key === 'z' || key === 'Z' || key === ' ') {
            if (this._goFocus === 0) {
                this.hideGameOver();
                this.game.loadStage(this.game.stageIndex);
            } else {
                this.hideGameOver();
                this.game.returnToMenu();
            }
        }
    }

    hideAll() {
        this.menuOverlay.style.display = 'none';
        this.gameoverOverlay.style.display = 'none';
        document.getElementById('pause-overlay').style.display = 'none';
        document.getElementById('title-overlay').style.display = 'none';
        document.getElementById('sub-overlay').style.display = 'none';
        document.getElementById('gallery-overlay').style.display = 'none';
        document.getElementById('achievements-overlay').style.display = 'none';
        document.getElementById('options-overlay').style.display = 'none';
        document.getElementById('howtoplay-overlay').style.display = 'none';
        document.getElementById('ending-overlay').style.display = 'none';
        const crEl = document.getElementById('creator-overlay');
        if (crEl) crEl.style.display = 'none';

        document.getElementById('ui-top-row').style.display = 'none';
        document.getElementById('ui').style.display = 'none';
        document.getElementById('controls').style.display = 'none';
        document.getElementById('reset-btn').style.display = 'none';
    }

    showGameUI() {
        document.getElementById('ui-top-row').style.display = 'flex';
        document.getElementById('ui').style.display = 'flex';
        document.getElementById('controls').style.display = 'flex';
    }

    showGallery() {
        this.hideAll();
        this._galleryLbStage = null;
        this._galleryLbState = 0; // 0=hidden 1=reveal
        document.getElementById('gallery-overlay').style.display = 'flex';

        const ach    = this.game.achievements;
        if (ach) ach.onGalleryView();
        const stages = STAGE_DATA.FREE;
        const clearedCount = stages.filter(s => ach.stats.bestErosion[s.id] != null).length;
        document.getElementById('gallery-count').innerText = `${clearedCount} / ${stages.length} 解放`;

        const grid = document.getElementById('gallery-grid');
        grid.innerHTML = '';

        stages.forEach(stage => {
            const isCleared = ach.stats.bestErosion[stage.id] != null;
            const cell = document.createElement('div');
            cell.className = 'gallery-cell ' + (isCleared ? 'cleared' : 'locked');

            const numLabel = `<div class="gallery-num">stage${stage.id}</div>`;
            if (isCleared && stage.assets && stage.assets.hidden) {
                cell.innerHTML = `<div class="gallery-cell-inner"><img class="gallery-thumb" src="${stage.assets.hidden}" loading="lazy" alt="">${numLabel}</div>`;
                cell.onclick = () => this._openGalleryLb(stage);
            } else {
                cell.innerHTML = `<div class="gallery-cell-inner"><div class="gallery-lock">🔒</div>${numLabel}</div>`;
            }
            grid.appendChild(cell);
        });
    }

    _openGalleryLb(stage) {
        this._galleryLbStage = stage;
        this._galleryLbState = 0;
        this._updateGalleryLb();
        document.getElementById('gallery-lb').classList.add('open');
    }

    _updateGalleryLb() {
        const stage = this._galleryLbStage;
        const img   = document.getElementById('gallery-lb-img');
        const hint  = document.getElementById('gallery-lb-hint');
        if (this._galleryLbState === 0) {
            img.src = stage.assets.hidden;
            hint.textContent = 'TAP → REVEAL IMAGE';
        } else {
            img.src = stage.assets.reveal;
            hint.textContent = 'TAP → BACK TO GALLERY';
        }
    }

    galleryLbClick() {
        if (this._galleryLbState === 0) {
            this._galleryLbState = 1;
            this._updateGalleryLb();
        } else {
            document.getElementById('gallery-lb').classList.remove('open');
            document.getElementById('gallery-lb-img').src = '';
            this._galleryLbStage = null;
        }
    }

    hideGallery() {
        document.getElementById('gallery-lb').classList.remove('open');
        document.getElementById('gallery-overlay').style.display = 'none';
    }

    showAchievements() {
        this.hideAll();
        const overlay = document.getElementById('achievements-overlay');
        overlay.style.display = 'flex';

        const ach  = this.game.achievements;
        const prog = ach.getProgress();
        document.getElementById('ach-progress').innerText =
            `${prog.unlocked} / ${prog.total} 解除`;

        const container = document.getElementById('ach-list');
        container.innerHTML = '';

        const cats = ['入門','標準','熟練','上級','伝説'];
        cats.forEach(cat => {
            const items = ACHIEVEMENTS.filter(a => a.cat === cat);
            if (items.length === 0) return;

            const unlockedCount = items.filter(a => ach.isUnlocked(a.id)).length;

            const header = document.createElement('div');
            header.className = 'ach-cat-header';
            header.innerHTML = `<span>${cat}</span><span class="ach-cat-count">${unlockedCount}/${items.length}</span>`;
            container.appendChild(header);

            const grid = document.createElement('div');
            grid.className = 'ach-grid';

            items.forEach(a => {
                const unlocked = ach.isUnlocked(a.id);
                const card = document.createElement('div');
                card.className = 'ach-card' + (unlocked ? ' unlocked' : ' locked');

                let progHtml = '';
                if (a.prog && !unlocked) {
                    const st = ach.stats[a.prog.stat];
                    const cur = (st instanceof Set) ? st.size : (st || 0);
                    progHtml = `<div class="ach-card-prog">${cur} / ${a.prog.target}</div>`;
                }

                if (a.hidden && !unlocked) {
                    card.innerHTML = `
                        <div class="ach-card-name">${a.name}</div>
                        <div class="ach-card-desc">???</div>${progHtml}`;
                } else {
                    card.innerHTML = `
                        <div class="ach-card-name">${a.name}</div>
                        <div class="ach-card-desc">${a.desc}</div>${progHtml}`;
                }
                grid.appendChild(card);
            });

            container.appendChild(grid);
        });
    }

    hideAchievements() {
        document.getElementById('achievements-overlay').style.display = 'none';
    }

    showOptions() {
        this.hideAll();
        const opts = this.game.options;
        document.getElementById('opt-bgm-vol').value  = opts.bgmVol;
        document.getElementById('opt-bgm-val').innerText = opts.bgmVol;
        document.getElementById('opt-sfx-vol').value  = opts.sfxVol;
        document.getElementById('opt-sfx-val').innerText = opts.sfxVol;
        document.getElementById('opt-dead-zone').value = opts.stickDead;
        document.getElementById('opt-dead-val').innerText = opts.stickDead;
        document.getElementById('opt-turn-delay').value = opts.turnDelay;
        document.getElementById('opt-turn-val').innerText = opts.turnDelay;

        const wire = (sliderId, valId, key, applyFn) => {
            const el = document.getElementById(sliderId);
            el.oninput = () => {
                const v = parseInt(el.value);
                document.getElementById(valId).innerText = v;
                this.game.options[key] = v;
                this.game.saveOptions();
                if (applyFn) applyFn(v);
            };
        };
        wire('opt-bgm-vol',   'opt-bgm-val',  'bgmVol',    v => this.game.audio.setBgmVolume(v));
        wire('opt-sfx-vol',   'opt-sfx-val',  'sfxVol',    v => this.game.audio.setSfxVolume(v));
        wire('opt-dead-zone', 'opt-dead-val', 'stickDead', null);
        wire('opt-turn-delay','opt-turn-val', 'turnDelay', null);

        document.getElementById('options-overlay').style.display = 'flex';
    }

    hideOptions() {
        document.getElementById('options-overlay').style.display = 'none';
    }

    showHowToPlay() {
        this.hideAll();
        if (!this._htp) {
            this._htp = new HowToPlay();
            this._htp.attach(document.getElementById('htp-canvas'), () => this._htpUpdateUI());
        }
        document.getElementById('howtoplay-overlay').style.display = 'flex';
        this._htp.goto(0);
        this._htp.start();
        this._htpUpdateUI();
    }

    hideHowToPlay() {
        if (this._htp) this._htp.stop();
        document.getElementById('howtoplay-overlay').style.display = 'none';
    }

    htpNext() { if (this._htp) { this._htp.next(); this._htpUpdateUI(); } }
    htpPrev() { if (this._htp) { this._htp.prev(); this._htpUpdateUI(); } }

    _htpUpdateUI() {
        const htp = this._htp;
        const demo = htp.demos[htp.current];
        document.getElementById('htp-pager').innerText = `${htp.current + 1} / ${htp.demos.length}`;
        document.getElementById('htp-demo-title').innerText = demo.title;
        document.getElementById('htp-demo-desc').innerText = demo.desc;
        const dots = document.getElementById('htp-dots');
        dots.innerHTML = htp.demos.map((_, i) =>
            `<div class="htp-dot${i === htp.current ? ' active' : ''}" onclick="game.ui._htpGoto(${i})"></div>`
        ).join('');
    }

    _htpGoto(i) { if (this._htp) { this._htp.goto(i); this._htpUpdateUI(); } }
}