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

import { escapeHtml } from '../../core/api.ts';
import { _cachedValueSources, audioSourcesCache } from '../../core/state.ts';
import { t } from '../../core/i18n.ts';
import { getAudioSourceIcon } from '../../core/icons.ts';
import * as P from '../../core/icon-paths.ts';
import { IconSelect } from '../../core/icon-select.ts';
import { EntitySelect } from '../../core/entity-palette.ts';
import { BindableScalarWidget } from '../../core/bindable-scalar.ts';
import { BindableColorWidget } from '../../core/bindable-color.ts';

const _icon = (d: any) => `<svg class="icon" viewBox="0 0 24 24">${d}</svg>`;

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

let _audioSensitivityWidget: BindableScalarWidget | null = null;
let _audioSmoothingWidget: BindableScalarWidget | null = null;
let _audioBeatDecayWidget: BindableScalarWidget | null = null;
let _audioColorWidget: BindableColorWidget | null = null;
let _audioColorPeakWidget: BindableColorWidget | null = null;
let _cssAudioSourceEntitySelect: any = null;
let _audioVizIconSelect: any = null;
let _audioPaletteEntitySelect: EntitySelect | null = null;

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

export function destroyAudioWidgets() {
    if (_audioSensitivityWidget) { _audioSensitivityWidget.destroy(); _audioSensitivityWidget = null; }
    if (_audioSmoothingWidget) { _audioSmoothingWidget.destroy(); _audioSmoothingWidget = null; }
    if (_audioColorWidget) { _audioColorWidget.destroy(); _audioColorWidget = null; }
    if (_audioColorPeakWidget) { _audioColorPeakWidget.destroy(); _audioColorPeakWidget = null; }
}

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

export function ensureAudioSensitivityWidget(): BindableScalarWidget {
    if (!_audioSensitivityWidget) {
        _audioSensitivityWidget = new BindableScalarWidget({
            container: document.getElementById('css-editor-audio-sensitivity-container')!,
            min: 0.1, max: 5.0, step: 0.1, default: 1.0,
            idPrefix: 'css-editor-audio-sensitivity',
            valueSources: () => _cachedValueSources,
            format: (v) => v.toFixed(1),
        });
    }
    return _audioSensitivityWidget;
}

export function ensureAudioSmoothingWidget(): BindableScalarWidget {
    if (!_audioSmoothingWidget) {
        _audioSmoothingWidget = new BindableScalarWidget({
            container: document.getElementById('css-editor-audio-smoothing-container')!,
            min: 0.0, max: 1.0, step: 0.05, default: 0.3,
            idPrefix: 'css-editor-audio-smoothing',
            valueSources: () => _cachedValueSources,
            format: (v) => v.toFixed(2),
        });
    }
    return _audioSmoothingWidget;
}

export function ensureAudioBeatDecayWidget(): BindableScalarWidget {
    if (!_audioBeatDecayWidget) {
        _audioBeatDecayWidget = new BindableScalarWidget({
            container: document.getElementById('css-editor-audio-beat-decay-container')!,
            min: 0.01, max: 0.5, step: 0.01, default: 0.15,
            idPrefix: 'css-editor-audio-beat-decay',
            valueSources: () => _cachedValueSources,
            format: (v) => v.toFixed(2),
        });
    }
    return _audioBeatDecayWidget;
}

export function ensureAudioColorWidget(): BindableColorWidget {
    if (!_audioColorWidget) {
        _audioColorWidget = new BindableColorWidget({
            container: document.getElementById('css-editor-audio-color-container')!,
            default: [0, 255, 0],
            valueSources: () => _cachedValueSources,
            idPrefix: 'css-editor-audio-color',
        });
    }
    return _audioColorWidget;
}

export function ensureAudioColorPeakWidget(): BindableColorWidget {
    if (!_audioColorPeakWidget) {
        _audioColorPeakWidget = new BindableColorWidget({
            container: document.getElementById('css-editor-audio-color-peak-container')!,
            default: [255, 0, 0],
            valueSources: () => _cachedValueSources,
            idPrefix: 'css-editor-audio-color-peak',
        });
    }
    return _audioColorPeakWidget;
}

/* ── IconSelect / EntitySelect ────────────────────────���───────── */

export function ensureAudioVizIconSelect() {
    const sel = document.getElementById('css-editor-audio-viz') as HTMLSelectElement | null;
    if (!sel) return;
    const items = [
        { value: 'spectrum',        icon: _icon(P.activity),   label: t('color_strip.audio.viz.spectrum'),        desc: t('color_strip.audio.viz.spectrum.desc') },
        { value: 'beat_pulse',      icon: _icon(P.zap),        label: t('color_strip.audio.viz.beat_pulse'),      desc: t('color_strip.audio.viz.beat_pulse.desc') },
        { value: 'vu_meter',        icon: _icon(P.trendingUp), label: t('color_strip.audio.viz.vu_meter'),        desc: t('color_strip.audio.viz.vu_meter.desc') },
        { value: 'pulse_on_beat',   icon: _icon(P.heart),      label: t('color_strip.audio.viz.pulse_on_beat'),   desc: t('color_strip.audio.viz.pulse_on_beat.desc') },
        { value: 'energy_gradient', icon: _icon(P.flame),      label: t('color_strip.audio.viz.energy_gradient'), desc: t('color_strip.audio.viz.energy_gradient.desc') },
        { value: 'spectrum_bands',  icon: _icon(P.radio),      label: t('color_strip.audio.viz.spectrum_bands'),  desc: t('color_strip.audio.viz.spectrum_bands.desc') },
        { value: 'strobe_on_drop',  icon: _icon(P.sparkles),   label: t('color_strip.audio.viz.strobe_on_drop'), desc: t('color_strip.audio.viz.strobe_on_drop.desc') },
    ];
    if (_audioVizIconSelect) { _audioVizIconSelect.updateItems(items); return; }
    _audioVizIconSelect = new IconSelect({ target: sel, items, columns: 4 });
}

export function ensureAudioPaletteEntitySelect(buildGradientEntityItems: () => any[], syncSelectOptions: (sel: HTMLSelectElement, items: any[]) => void) {
    const sel = document.getElementById('css-editor-audio-palette') as HTMLSelectElement | null;
    if (!sel) return;
    const items = buildGradientEntityItems();
    syncSelectOptions(sel, items);
    if (_audioPaletteEntitySelect) { _audioPaletteEntitySelect.refresh(); return; }
    _audioPaletteEntitySelect = new EntitySelect({
        target: sel,
        getItems: buildGradientEntityItems,
        placeholder: t('palette.search'),
    });
}

export function refreshAudioPaletteEntitySelect() {
    if (_audioPaletteEntitySelect) _audioPaletteEntitySelect.refresh();
}

export function getAudioVizIconSelect() { return _audioVizIconSelect; }
export function getAudioPaletteEntitySelect() { return _audioPaletteEntitySelect; }

/* ── Audio source loading ─────────────────��───────────────────── */

export async function loadAudioSources() {
    const select = document.getElementById('css-editor-audio-source') as HTMLSelectElement | null;
    if (!select) return;
    try {
        const sources: any[] = await audioSourcesCache.fetch();
        select.innerHTML = sources.map(s => {
            const badge = s.source_type === 'capture' ? ' [capture]' : ' [processed]';
            return `<option value="${s.id}">${escapeHtml(s.name)}${badge}</option>`;
        }).join('');
        if (sources.length === 0) {
            select.innerHTML = '';
        }
        if (_cssAudioSourceEntitySelect) _cssAudioSourceEntitySelect.destroy();
        if (sources.length > 0) {
            _cssAudioSourceEntitySelect = new EntitySelect({
                target: select,
                getItems: () => sources.map(s => ({
                    value: s.id,
                    label: s.name,
                    icon: getAudioSourceIcon(s.source_type),
                    desc: s.source_type,
                })),
                placeholder: t('palette.search'),
            });
        }
    } catch {
        select.innerHTML = '';
    }
}

/* ── Load / Reset state ───────────────────────────────────────── */

export function loadAudioState(css: any) {
    (document.getElementById('css-editor-audio-viz') as HTMLInputElement).value = css.visualization_mode || 'spectrum';
    if (_audioVizIconSelect) _audioVizIconSelect.setValue(css.visualization_mode || 'spectrum');

    ensureAudioSensitivityWidget().setValue(css.sensitivity ?? 1.0);
    ensureAudioSmoothingWidget().setValue(css.smoothing ?? 0.3);
    ensureAudioBeatDecayWidget().setValue(css.beat_decay ?? 0.15);

    const audioGradientId = css.gradient_id || 'gr_builtin_rainbow';
    (document.getElementById('css-editor-audio-palette') as HTMLInputElement).value = audioGradientId;
    if (_audioPaletteEntitySelect) _audioPaletteEntitySelect.setValue(audioGradientId);
    ensureAudioColorWidget().setValue(css.color);
    ensureAudioColorPeakWidget().setValue(css.color_peak);
    (document.getElementById('css-editor-audio-mirror') as HTMLInputElement).checked = css.mirror || false;

    const select = document.getElementById('css-editor-audio-source') as HTMLSelectElement | null;
    if (select && css.audio_source_id) {
        select.value = css.audio_source_id;
    }
}

export function resetAudioState() {
    (document.getElementById('css-editor-audio-viz') as HTMLInputElement).value = 'spectrum';
    if (_audioVizIconSelect) _audioVizIconSelect.setValue('spectrum');
    ensureAudioSensitivityWidget().setValue(1.0);
    ensureAudioSmoothingWidget().setValue(0.3);
    ensureAudioBeatDecayWidget().setValue(0.15);
    (document.getElementById('css-editor-audio-palette') as HTMLInputElement).value = 'gr_builtin_rainbow';
    if (_audioPaletteEntitySelect) _audioPaletteEntitySelect.setValue('gr_builtin_rainbow');
    ensureAudioColorWidget().setValue([0, 255, 0]);
    ensureAudioColorPeakWidget().setValue([255, 0, 0]);
    (document.getElementById('css-editor-audio-mirror') as HTMLInputElement).checked = false;
}
