/**
 * Color Strip Sources — Game Event helpers.
 * Extracted from color-strips.ts to reduce file size.
 */

import { escapeHtml } from '../../core/api.ts';
import { _cachedGameIntegrations, _cachedGameAdapters, _cachedValueSources } from '../../core/state.ts';
import { t } from '../../core/i18n.ts';
import { ICON_TRASH, ICON_GAMEPAD } from '../../core/icons.ts';
import * as P from '../../core/icon-paths.ts';
import { IconSelect, type IconSelectItem } from '../../core/icon-select.ts';
import { EntitySelect } from '../../core/entity-palette.ts';
import { BindableColorWidget } from '../../core/bindable-color.ts';

/* ── State ────────────────────────────────────────────────────── */

let _gameEventIdleColorWidget: BindableColorWidget | null = null;
let _cssGameIntegrationEntitySelect: EntitySelect | null = null;
let _cssGameMappings: any[] = [];
let _cssGameMappingIconSelects: IconSelect[] = [];
let _cssGamePresetIconSelect: IconSelect | null = null;

/* ── Destroy helpers (called from modal onForceClose) ─────────── */

export function destroyGameEventWidgets() {
    if (_gameEventIdleColorWidget) { _gameEventIdleColorWidget.destroy(); _gameEventIdleColorWidget = null; }
    if (_cssGameIntegrationEntitySelect) { _cssGameIntegrationEntitySelect.destroy(); _cssGameIntegrationEntitySelect = null; }
    destroyCSSGameMappingIconSelects();
    if (_cssGamePresetIconSelect) { _cssGamePresetIconSelect.destroy(); _cssGamePresetIconSelect = null; }
}

function destroyCSSGameMappingIconSelects() {
    _cssGameMappingIconSelects.forEach(is => is.destroy());
    _cssGameMappingIconSelects = [];
}

/* ── Color/hex helpers ────────────────────────────────────────── */

function _hexToRgbCSS(hex: string): number[] {
    const m = hex.replace('#', '').match(/.{2}/g);
    if (!m) return [255, 0, 0];
    return m.map(c => parseInt(c, 16));
}

function _rgbToHexCSS(rgb: number[]): string {
    return '#' + rgb.map(c => c.toString(16).padStart(2, '0')).join('');
}

/* ── Available event types ────────────────────────────────────── */

function _getCSSGameAvailableEventTypes(): string[] {
    const giId = (document.getElementById('css-editor-game-integration') as HTMLSelectElement)?.value;
    if (giId) {
        const gi = (_cachedGameIntegrations || []).find(g => g.id === giId);
        if (gi) {
            const adapter = (_cachedGameAdapters || []).find(a => a.adapter_type === gi.adapter_type);
            if (adapter && adapter.supported_events.length > 0) return adapter.supported_events;
        }
    }
    return ['kill', 'death', 'health', 'armor', 'round_start', 'round_end', 'bomb_planted', 'bomb_defused', 'assist', 'headshot'];
}

/* ── Constants ────────────────────────────────────────────────── */

const _CSS_GE_EFFECT_TYPES: IconSelectItem[] = [
    { value: 'flash', label: 'Flash', icon: `<svg class="icon" viewBox="0 0 24 24">${P.zap}</svg>` },
    { value: 'pulse', label: 'Pulse', icon: `<svg class="icon" viewBox="0 0 24 24">${P.activity}</svg>` },
    { value: 'sweep', label: 'Sweep', icon: `<svg class="icon" viewBox="0 0 24 24">${P.fastForward}</svg>` },
    { value: 'color_shift', label: 'Color Shift', icon: `<svg class="icon" viewBox="0 0 24 24">${P.rainbow}</svg>` },
    { value: 'breathing', label: 'Breathing', icon: `<svg class="icon" viewBox="0 0 24 24">${P.heart}</svg>` },
];

const _CSS_GE_EVENT_ICONS: Record<string, string> = {
    kill: P.crosshair, death: P.xIcon, health: P.heart, armor: P.shield,
    round_start: P.play, round_end: P.square, bomb_planted: P.flame, bomb_defused: P.circleCheck,
    assist: P.swords, headshot: P.target, damage: P.zap, gold: P.star,
    level_up: P.trendingUp, respawn: P.refreshCw, item_pickup: P.packageIcon,
};

/* ── Build helpers ────────────────────────────────────────────── */

function _buildCSSGameEventTypeItems(): IconSelectItem[] {
    return _getCSSGameAvailableEventTypes().map(et => ({
        value: et,
        label: et,
        icon: `<svg class="icon" viewBox="0 0 24 24">${_CSS_GE_EVENT_ICONS[et] || P.circleDot}</svg>`,
    }));
}

/* ── Rendering ────────────────────────────────────────────────── */

function _renderCSSGameMappingRow(mapping: any, index: number): string {
    const eventTypes = _getCSSGameAvailableEventTypes();
    const eventOptions = eventTypes.map(et =>
        `<option value="${et}"${et === mapping.event_type ? ' selected' : ''}>${et}</option>`
    ).join('');
    const effectOptions = _CSS_GE_EFFECT_TYPES.map(ef =>
        `<option value="${ef.value}"${ef.value === mapping.effect_type ? ' selected' : ''}>${ef.label}</option>`
    ).join('');
    const effectLabel = _CSS_GE_EFFECT_TYPES.find(ef => ef.value === mapping.effect_type)?.label || mapping.effect_type;
    const hexColor = _rgbToHexCSS(mapping.color || [255, 0, 0]);

    return `
        <div class="gi-mapping-row" data-mapping-index="${index}">
            <div class="gi-mapping-header">
                <span class="gi-mapping-expand-btn">&#x25B6;</span>
                <span class="gi-mapping-summary">
                    <span class="gi-mapping-summary-event">${escapeHtml(mapping.event_type)}</span>
                    <span class="gi-mapping-summary-effect">${escapeHtml(effectLabel)}</span>
                    <span class="gi-mapping-summary-color" style="background:${hexColor}"></span>
                </span>
                <button type="button" class="btn-remove-rule" onclick="event.stopPropagation(); removeCSSGameMapping(${index})" title="${t('common.delete')}">${ICON_TRASH}</button>
            </div>
            <div class="gi-mapping-body-wrapper">
            <div class="gi-mapping-body">
                <div class="gi-mapping-field-row">
                    <label>${t('game_integration.mapping.event_type')}</label>
                    <select data-field="event_type">${eventOptions}</select>
                </div>
                <div class="gi-mapping-field-row">
                    <label>${t('game_integration.mapping.effect_type')}</label>
                    <select data-field="effect_type">${effectOptions}</select>
                </div>
                <div class="gi-mapping-field-row">
                    <label>${t('game_integration.mapping.color')}</label>
                    <input type="color" data-field="color" value="${hexColor}">
                </div>
                <div class="gi-mapping-field-row">
                    <label>${t('game_integration.mapping.duration')}</label>
                    <input type="number" data-field="duration_ms" value="${mapping.duration_ms || 500}" min="50" max="10000" step="50">
                </div>
                <div class="gi-mapping-field-row">
                    <label>${t('game_integration.mapping.intensity')}</label>
                    <input type="range" data-field="intensity" value="${mapping.intensity ?? 1.0}" min="0" max="1" step="0.05"
                        oninput="this.title = this.value">
                </div>
                <div class="gi-mapping-field-row">
                    <label>${t('game_integration.mapping.priority')}</label>
                    <input type="number" data-field="priority" value="${mapping.priority || 5}" min="1" max="10">
                </div>
            </div>
            </div>
        </div>`;
}

function _wireCSSGameMappingRows(container: HTMLElement) {
    container.querySelectorAll('.gi-mapping-header').forEach(header => {
        const item = header.closest('.gi-mapping-row') as HTMLElement;
        header.addEventListener('click', (e: Event) => {
            if ((e.target as HTMLElement).closest('.btn-remove-rule')) return;
            item.classList.toggle('gi-mapping-expanded');
        });
    });

    container.querySelectorAll('.gi-mapping-row').forEach(row => {
        const eventSel = row.querySelector('[data-field="event_type"]') as HTMLSelectElement | null;
        const effectSel = row.querySelector('[data-field="effect_type"]') as HTMLSelectElement | null;
        const colorInput = row.querySelector('input[data-field="color"]') as HTMLInputElement | null;
        const summaryEvent = row.querySelector('.gi-mapping-summary-event') as HTMLElement | null;
        const summaryEffect = row.querySelector('.gi-mapping-summary-effect') as HTMLElement | null;
        const summaryColor = row.querySelector('.gi-mapping-summary-color') as HTMLElement | null;

        if (eventSel) {
            const is = new IconSelect({ target: eventSel, items: _buildCSSGameEventTypeItems(), columns: 4 });
            _cssGameMappingIconSelects.push(is);
            if (summaryEvent) {
                eventSel.addEventListener('change', () => { summaryEvent.textContent = eventSel.value; });
            }
        }
        if (effectSel) {
            const is = new IconSelect({ target: effectSel, items: _CSS_GE_EFFECT_TYPES, columns: 3 });
            _cssGameMappingIconSelects.push(is);
            if (summaryEffect) {
                effectSel.addEventListener('change', () => {
                    const label = _CSS_GE_EFFECT_TYPES.find(ef => ef.value === effectSel.value)?.label || effectSel.value;
                    summaryEffect.textContent = label;
                });
            }
        }
        if (colorInput && summaryColor) {
            colorInput.addEventListener('input', () => { summaryColor.style.background = colorInput.value; });
        }
    });
}

function _renderCSSGameMappings(mappings: any[]) {
    _cssGameMappings = [...mappings];
    destroyCSSGameMappingIconSelects();
    const container = document.getElementById('css-editor-ge-mappings-list');
    if (!container) return;
    container.innerHTML = mappings.map((m, i) => _renderCSSGameMappingRow(m, i)).join('');
    _wireCSSGameMappingRows(container);
}

export function collectCSSGameMappings(): any[] {
    const rows = document.querySelectorAll('#css-editor-ge-mappings-list .gi-mapping-row');
    return Array.from(rows).map(row => {
        const eventType = (row.querySelector('[data-field="event_type"]') as HTMLSelectElement)?.value || 'kill';
        const effectType = (row.querySelector('[data-field="effect_type"]') as HTMLSelectElement)?.value || 'flash';
        const colorInput = (row.querySelector('input[data-field="color"]') as HTMLInputElement)?.value || '#ff0000';
        const duration = parseFloat((row.querySelector('[data-field="duration_ms"]') as HTMLInputElement)?.value) || 500;
        const intensity = parseFloat((row.querySelector('[data-field="intensity"]') as HTMLInputElement)?.value) || 1.0;
        const priority = parseInt((row.querySelector('[data-field="priority"]') as HTMLInputElement)?.value) || 5;
        return { event_type: eventType, effect_type: effectType, color: _hexToRgbCSS(colorInput), duration_ms: duration, intensity, priority };
    });
}

/* ── Public actions ───────────────────────────────────────────── */

export function addCSSGameMapping() {
    const collected = collectCSSGameMappings();
    collected.push({
        event_type: _getCSSGameAvailableEventTypes()[0] || 'kill',
        effect_type: 'flash',
        color: [255, 0, 0],
        duration_ms: 500,
        intensity: 1.0,
        priority: 5,
    });
    _renderCSSGameMappings(collected);
}

export function removeCSSGameMapping(index: number) {
    const collected = collectCSSGameMappings();
    collected.splice(index, 1);
    _renderCSSGameMappings(collected);
}

export function onCSSGameMappingPresetChange() {
    const sel = document.getElementById('css-editor-ge-mapping-preset') as HTMLSelectElement;
    if (!sel.value) return;
    const presets: Record<string, any[]> = {
        fps_combat: [
            { event_type: 'kill', effect_type: 'flash', color: [0, 255, 0], duration_ms: 400, intensity: 1.0, priority: 8 },
            { event_type: 'death', effect_type: 'pulse', color: [255, 0, 0], duration_ms: 1500, intensity: 1.0, priority: 10 },
            { event_type: 'headshot', effect_type: 'flash', color: [255, 215, 0], duration_ms: 300, intensity: 1.0, priority: 9 },
            { event_type: 'health', effect_type: 'breathing', color: [255, 50, 50], duration_ms: 2000, intensity: 0.6, priority: 3 },
            { event_type: 'round_start', effect_type: 'sweep', color: [0, 100, 255], duration_ms: 800, intensity: 0.8, priority: 5 },
        ],
        moba_health: [
            { event_type: 'health', effect_type: 'color_shift', color: [0, 255, 0], duration_ms: 1000, intensity: 0.7, priority: 4 },
            { event_type: 'kill', effect_type: 'flash', color: [255, 215, 0], duration_ms: 500, intensity: 1.0, priority: 8 },
            { event_type: 'death', effect_type: 'pulse', color: [255, 0, 0], duration_ms: 2000, intensity: 1.0, priority: 10 },
            { event_type: 'assist', effect_type: 'flash', color: [100, 200, 255], duration_ms: 300, intensity: 0.8, priority: 6 },
        ],
    };
    const preset = presets[sel.value];
    if (preset) _renderCSSGameMappings(preset);
    sel.value = '';
}

export function initCSSGamePresetIconSelect() {
    const sel = document.getElementById('css-editor-ge-mapping-preset') as HTMLSelectElement | null;
    if (!sel) return;
    if (_cssGamePresetIconSelect) { _cssGamePresetIconSelect.destroy(); _cssGamePresetIconSelect = null; }
    const items: IconSelectItem[] = [
        { value: '', label: t('game_integration.mapping.select_preset'), icon: '' },
        { value: 'fps_combat', label: t('game_integration.preset.fps_combat'), icon: `<svg class="icon" viewBox="0 0 24 24">${P.crosshair}</svg>` },
        { value: 'moba_health', label: t('game_integration.preset.moba_health'), icon: `<svg class="icon" viewBox="0 0 24 24">${P.heart}</svg>` },
    ];
    _cssGamePresetIconSelect = new IconSelect({ target: sel, items, columns: 2 });
}

/* ── Widget ensure helpers ────────────────────────────────────── */

export function ensureGameEventIdleColorWidget(): BindableColorWidget {
    if (!_gameEventIdleColorWidget) {
        _gameEventIdleColorWidget = new BindableColorWidget({
            container: document.getElementById('css-editor-game-event-idle-color-container')!,
            default: [0, 0, 0],
            valueSources: () => _cachedValueSources,
            idPrefix: 'css-editor-ge-idle-color',
        });
    }
    return _gameEventIdleColorWidget;
}

export function populateGameIntegrationDropdownCSS(selectedId: string = '') {
    const sel = document.getElementById('css-editor-game-integration') as HTMLSelectElement;
    const integrations = _cachedGameIntegrations || [];
    const prev = selectedId || sel.value;
    sel.innerHTML = `<option value="">${t('common.none_no_input')}</option>` +
        integrations.map(gi => `<option value="${gi.id}"${gi.id === prev ? ' selected' : ''}>${escapeHtml(gi.name)}</option>`).join('');
    sel.value = prev || '';

    if (_cssGameIntegrationEntitySelect) _cssGameIntegrationEntitySelect.destroy();
    _cssGameIntegrationEntitySelect = new EntitySelect({
        target: sel,
        getItems: () => integrations.map(gi => ({
            value: gi.id,
            label: gi.name,
            icon: ICON_GAMEPAD,
            desc: gi.adapter_type,
        })),
        allowNone: true,
        noneLabel: t('common.none_no_input'),
        placeholder: t('palette.search'),
    });
}

export function renderCSSGameMappings(mappings: any[]) {
    _renderCSSGameMappings(mappings);
}

/** Get raw mappings array (for snapshot). */
export function getCSSGameMappings(): any[] {
    return _cssGameMappings;
}
