/**
 * Audio Processing Templates — CRUD for audio filter chain templates.
 *
 * Audio processing templates define ordered lists of audio filters
 * (channel_extract, band_extract, gain, compressor, etc.) that are
 * applied to AudioAnalysis data in the stream pipeline.
 *
 * Card rendering is called from streams.ts (Audio Processing Templates tab).
 * This module manages the editor modal and API operations.
 */

import {
    _cachedAudioProcessingTemplates,
    audioProcessingTemplatesCache,
    _cachedAudioFilterDefs,
    audioFilterDefsCache,
} from '../core/state.ts';
import { fetchWithAuth, escapeHtml } from '../core/api.ts';
import { t } from '../core/i18n.ts';
import { showToast, showConfirm } from '../core/ui.ts';
import { Modal } from '../core/modal.ts';
import { ICON_AUDIO_TEMPLATE, ICON_CLONE, ICON_EDIT } from '../core/icons.ts';
import { TagInput, renderTagChips } from '../core/tag-input.ts';
import { FilterListManager } from '../core/filter-list.ts';
import { wrapCard } from '../core/card-colors.ts';
import { loadPictureSources } from './streams.ts';

// ── Module state ─────────────────────────────────────────────

let _aptTagsInput: TagInput | null = null;
let _aptModalFilters: any[] = [];
let _aptNameManuallyEdited = false;

// ── Modal ────────────────────────────────────────────────────

class AudioProcessingTemplateModal extends Modal {
    constructor() { super('apt-modal'); }

    snapshotValues() {
        return {
            name: (document.getElementById('apt-name') as HTMLInputElement).value,
            description: (document.getElementById('apt-description') as HTMLInputElement).value,
            filters: JSON.stringify(_aptModalFilters.map(fi => ({ filter_id: fi.filter_id, options: fi.options }))),
            tags: JSON.stringify(_aptTagsInput ? _aptTagsInput.getValue() : []),
        };
    }

    onForceClose() {
        if (_aptTagsInput) { _aptTagsInput.destroy(); _aptTagsInput = null; }
        _aptModalFilters = [];
        _aptNameManuallyEdited = false;
    }
}

const aptModal = new AudioProcessingTemplateModal();

// ── Helper: get audio filter name from registry ──────────────

function _getAudioFilterName(filterId: string): string {
    const defs = _cachedAudioFilterDefs;
    const def = defs.find((f: any) => f.filter_id === filterId);
    return def ? def.filter_name : filterId;
}

// ── FilterListManager instance ───────────────────────────────

const aptFilterManager = new FilterListManager({
    getFilters: () => _aptModalFilters,
    getFilterDefs: () => _cachedAudioFilterDefs,
    getFilterName: _getAudioFilterName,
    selectId: 'apt-add-filter-select',
    containerId: 'apt-filter-list',
    prefix: 'apt',
    editingIdInputId: 'apt-id',
    selfRefFilterId: 'audio_filter_template',
    autoNameFn: () => _autoGenerateAPTName(),
});

// ── Auto-name generation ─────────────────────────────────────

function _autoGenerateAPTName() {
    if (_aptNameManuallyEdited) return;
    if ((document.getElementById('apt-id') as HTMLInputElement).value) return;
    const nameInput = document.getElementById('apt-name') as HTMLInputElement;
    if (_aptModalFilters.length > 0) {
        const filterNames = _aptModalFilters.map(f => _getAudioFilterName(f.filter_id)).join(' + ');
        nameInput.value = filterNames;
    } else {
        nameInput.value = '';
    }
}

// ── Collect filters for save ─────────────────────────────────

function _collectAPTFilters(): any[] {
    return aptFilterManager.collect();
}

// ── Show modal (create / clone) ──────────────────────────────

export async function showAudioProcessingTemplateModal(cloneData: any = null) {
    // Ensure audio filter definitions are loaded
    if (_cachedAudioFilterDefs.length === 0) await audioFilterDefsCache.fetch();

    document.getElementById('apt-modal-title')!.innerHTML = `${ICON_AUDIO_TEMPLATE} ${t('audio_processing.add')}`;
    (document.getElementById('apt-id') as HTMLInputElement).value = '';
    (document.getElementById('apt-name') as HTMLInputElement).value = '';
    (document.getElementById('apt-description') as HTMLInputElement).value = '';
    (document.getElementById('apt-error') as HTMLElement).style.display = 'none';

    if (cloneData) {
        _aptModalFilters = (cloneData.filters || []).map((fi: any) => ({
            filter_id: fi.filter_id,
            options: { ...fi.options },
        }));
        _aptNameManuallyEdited = true;
    } else {
        _aptModalFilters = [];
        _aptNameManuallyEdited = false;
    }
    (document.getElementById('apt-name') as HTMLInputElement).oninput = () => { _aptNameManuallyEdited = true; };

    aptFilterManager.populateSelect(() => aptAddFilterFromSelect());
    renderAPTModalFilterList();

    if (cloneData) {
        (document.getElementById('apt-name') as HTMLInputElement).value = (cloneData.name || '') + ' (Copy)';
        (document.getElementById('apt-description') as HTMLInputElement).value = cloneData.description || '';
    }

    // Tags
    if (_aptTagsInput) { _aptTagsInput.destroy(); _aptTagsInput = null; }
    _aptTagsInput = new TagInput(document.getElementById('apt-tags-container'), { placeholder: t('tags.placeholder') });
    _aptTagsInput.setValue(cloneData ? (cloneData.tags || []) : []);

    aptModal.open();
    aptModal.snapshot();
}

// ── Edit ──────────────────────────────────────────────────────

export async function editAudioProcessingTemplate(templateId: string) {
    try {
        if (_cachedAudioFilterDefs.length === 0) await audioFilterDefsCache.fetch();

        const response = await fetchWithAuth(`/audio-processing-templates/${templateId}`);
        if (!response.ok) throw new Error(`Failed to load template: ${response.status}`);
        const tmpl = await response.json();

        document.getElementById('apt-modal-title')!.innerHTML = `${ICON_AUDIO_TEMPLATE} ${t('audio_processing.edit')}`;
        (document.getElementById('apt-id') as HTMLInputElement).value = templateId;
        (document.getElementById('apt-name') as HTMLInputElement).value = tmpl.name;
        (document.getElementById('apt-description') as HTMLInputElement).value = tmpl.description || '';
        (document.getElementById('apt-error') as HTMLElement).style.display = 'none';

        _aptModalFilters = (tmpl.filters || []).map((fi: any) => ({
            filter_id: fi.filter_id,
            options: { ...fi.options },
        }));
        _aptNameManuallyEdited = true;

        aptFilterManager.populateSelect(() => aptAddFilterFromSelect());
        renderAPTModalFilterList();

        // Tags
        if (_aptTagsInput) { _aptTagsInput.destroy(); _aptTagsInput = null; }
        _aptTagsInput = new TagInput(document.getElementById('apt-tags-container'), { placeholder: t('tags.placeholder') });
        _aptTagsInput.setValue(tmpl.tags || []);

        aptModal.open();
        aptModal.snapshot();
    } catch (error: any) {
        if (error.isAuth) return;
        showToast(t('audio_processing.error.load') + ': ' + error.message, 'error');
    }
}

// ── Save ──────────────────────────────────────────────────────

export async function saveAudioProcessingTemplate() {
    const templateId = (document.getElementById('apt-id') as HTMLInputElement).value;
    const name = (document.getElementById('apt-name') as HTMLInputElement).value.trim();
    const description = (document.getElementById('apt-description') as HTMLInputElement).value.trim();

    if (!name) {
        aptModal.showError(t('audio_processing.error.required'));
        return;
    }

    const payload = {
        name,
        filters: _collectAPTFilters(),
        description: description || null,
        tags: _aptTagsInput ? _aptTagsInput.getValue() : [],
    };

    try {
        const url = templateId ? `/audio-processing-templates/${templateId}` : '/audio-processing-templates';
        const method = templateId ? 'PUT' : 'POST';
        const response = await fetchWithAuth(url, { method, body: JSON.stringify(payload) });

        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.detail || error.message || 'Failed to save template');
        }

        showToast(templateId ? t('audio_processing.updated') : t('audio_processing.created'), 'success');
        aptModal.forceClose();
        audioProcessingTemplatesCache.invalidate();
        await loadPictureSources();
    } catch (error: any) {
        if (error.isAuth) return;
        aptModal.showError(error.message);
    }
}

// ── Clone ─────────────────────────────────────────────────────

export async function cloneAudioProcessingTemplate(templateId: string) {
    try {
        const resp = await fetchWithAuth(`/audio-processing-templates/${templateId}`);
        if (!resp.ok) throw new Error('Failed to load template');
        const tmpl = await resp.json();
        await showAudioProcessingTemplateModal(tmpl);
    } catch (error: any) {
        if (error.isAuth) return;
        showToast(t('audio_processing.error.clone_failed') + ': ' + error.message, 'error');
    }
}

// ── Delete ────────────────────────────────────────────────────

export async function deleteAudioProcessingTemplate(templateId: string) {
    const confirmed = await showConfirm(t('audio_processing.delete.confirm'));
    if (!confirmed) return;

    try {
        const response = await fetchWithAuth(`/audio-processing-templates/${templateId}`, { method: 'DELETE' });
        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.detail || error.message || 'Failed to delete template');
        }
        showToast(t('audio_processing.deleted'), 'success');
        audioProcessingTemplatesCache.invalidate();
        await loadPictureSources();
    } catch (error: any) {
        if (error.isAuth) return;
        showToast(t('audio_processing.error.delete') + ': ' + error.message, 'error');
    }
}

// ── Close ─────────────────────────────────────────────────────

export async function closeAudioProcessingTemplateModal() {
    await aptModal.close();
}

// ── Filter list delegation (window-callable) ──────────────────

export function aptAddFilterFromSelect() { aptFilterManager.addFromSelect(); }
export function aptToggleFilterExpand(index: number) { aptFilterManager.toggleExpand(index); }
export function aptRemoveFilter(index: number) { aptFilterManager.remove(index); }
export function aptUpdateFilterOption(filterIndex: number, optionKey: string, value: any) { aptFilterManager.updateOption(filterIndex, optionKey, value); }
export function renderAPTModalFilterList() { aptFilterManager.render(); }

// ── Card rendering (used by streams.ts) ───────────────────────

export function createAudioProcessingTemplateCard(tmpl: any): string {
    let filterChainHtml = '';
    if (tmpl.filters && tmpl.filters.length > 0) {
        const filterNames = tmpl.filters.map((fi: any) => {
            let label = _getAudioFilterName(fi.filter_id);
            if (fi.filter_id === 'audio_filter_template' && fi.options?.template_id) {
                const ref = _cachedAudioProcessingTemplates.find((p: any) => p.id === fi.options.template_id);
                if (ref) label += `: ${ref.name}`;
            }
            return `<span class="filter-chain-item">${escapeHtml(label)}</span>`;
        });
        filterChainHtml = `<div class="filter-chain">${filterNames.join('<span class="filter-chain-arrow">\u2192</span>')}</div>`;
    }

    return wrapCard({
        type: 'template-card',
        dataAttr: 'data-apt-id',
        id: tmpl.id,
        removeOnclick: `deleteAudioProcessingTemplate('${tmpl.id}')`,
        removeTitle: t('common.delete'),
        content: `
            <div class="template-card-header">
                <div class="template-name" title="${escapeHtml(tmpl.name)}">${ICON_AUDIO_TEMPLATE} ${escapeHtml(tmpl.name)}</div>
            </div>
            ${tmpl.description ? `<div class="template-config" style="opacity:0.7;">${escapeHtml(tmpl.description)}</div>` : ''}
            <div class="stream-card-props">
                <span class="stream-card-prop" title="${t('audio_processing.filter_count')}">${ICON_AUDIO_TEMPLATE} ${tmpl.filters ? tmpl.filters.length : 0} ${t('audio_processing.filters_label')}</span>
            </div>
            ${filterChainHtml}
            ${renderTagChips(tmpl.tags)}`,
        actions: `
                <button class="btn btn-icon btn-secondary" onclick="cloneAudioProcessingTemplate('${tmpl.id}')" title="${t('common.clone')}">${ICON_CLONE}</button>
                <button class="btn btn-icon btn-secondary" onclick="editAudioProcessingTemplate('${tmpl.id}')" title="${t('common.edit')}">${ICON_EDIT}</button>`,
    });
}
