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

import { fetchWithAuth, escapeHtml } from '../core/api.ts';
import { t } from '../core/i18n.ts';
import { showToast } from '../core/ui.ts';
import {
    ICON_SEARCH,
} from '../core/icons.ts';
import * as P from '../core/icon-paths.ts';
import { IconSelect } from '../core/icon-select.ts';
import { attachNotificationAppPicker, NotificationAppPalette } from '../core/process-picker.ts';
import { getBaseOrigin } from './settings.ts';

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

/* ── Notification state ───────────────────────────────────────── */

let _notificationAppColors: any[] = [];  // [{app: '', color: '#...'}]

/** Return current app colors array (for dirty-check snapshot). */
export function notificationGetRawAppColors() {
    return _notificationAppColors;
}
let _notificationEffectIconSelect: any = null;
let _notificationFilterModeIconSelect: any = null;

export function ensureNotificationEffectIconSelect() {
    const sel = document.getElementById('css-editor-notification-effect') as HTMLSelectElement | null;
    if (!sel) return;
    const items = [
        { value: 'flash', icon: _icon(P.zap),         label: t('color_strip.notification.effect.flash'), desc: t('color_strip.notification.effect.flash.desc') },
        { value: 'pulse', icon: _icon(P.activity),     label: t('color_strip.notification.effect.pulse'), desc: t('color_strip.notification.effect.pulse.desc') },
        { value: 'sweep', icon: _icon(P.fastForward),  label: t('color_strip.notification.effect.sweep'), desc: t('color_strip.notification.effect.sweep.desc') },
    ];
    if (_notificationEffectIconSelect) { _notificationEffectIconSelect.updateItems(items); return; }
    _notificationEffectIconSelect = new IconSelect({ target: sel, items, columns: 3 });
}

export function ensureNotificationFilterModeIconSelect() {
    const sel = document.getElementById('css-editor-notification-filter-mode') as HTMLSelectElement | null;
    if (!sel) return;
    const items = [
        { value: 'off',       icon: _icon(P.globe),    label: t('color_strip.notification.filter_mode.off'),       desc: t('color_strip.notification.filter_mode.off.desc') },
        { value: 'whitelist', icon: _icon(P.circleCheck), label: t('color_strip.notification.filter_mode.whitelist'), desc: t('color_strip.notification.filter_mode.whitelist.desc') },
        { value: 'blacklist', icon: _icon(P.eyeOff),   label: t('color_strip.notification.filter_mode.blacklist'), desc: t('color_strip.notification.filter_mode.blacklist.desc') },
    ];
    if (_notificationFilterModeIconSelect) { _notificationFilterModeIconSelect.updateItems(items); return; }
    _notificationFilterModeIconSelect = new IconSelect({ target: sel, items, columns: 3 });
}

export function onNotificationFilterModeChange() {
    const mode = (document.getElementById('css-editor-notification-filter-mode') as HTMLInputElement).value;
    (document.getElementById('css-editor-notification-filter-list-group') as HTMLElement).style.display = mode === 'off' ? 'none' : '';
}

function _notificationAppColorsRenderList() {
    const list = document.getElementById('notification-app-colors-list') as HTMLElement | null;
    if (!list) return;
    list.innerHTML = _notificationAppColors.map((entry, i) => `
        <div class="notif-app-color-row">
            <input type="text" class="notif-app-name" data-idx="${i}" value="${escapeHtml(entry.app)}" placeholder="App name">
            <button type="button" class="notif-app-browse" data-idx="${i}"
                    title="${t('automations.condition.application.browse')}">${ICON_SEARCH}</button>
            <input type="color" class="notif-app-color" data-idx="${i}" value="${entry.color}">
            <button type="button" class="notif-app-color-remove"
                    onclick="notificationRemoveAppColor(${i})">&#x2715;</button>
        </div>
    `).join('');

    // Wire up browse buttons to open process palette
    list.querySelectorAll<HTMLButtonElement>('.notif-app-browse').forEach(btn => {
        btn.addEventListener('click', async () => {
            const idx = parseInt(btn.dataset.idx!);
            const nameInput = list.querySelector<HTMLInputElement>(`.notif-app-name[data-idx="${idx}"]`);
            if (!nameInput) return;
            const picked = await NotificationAppPalette.pick({
                current: nameInput.value,
                placeholder: t('color_strip.notification.search_apps') || 'Search notification apps...',
            });
            if (picked !== undefined) {
                nameInput.value = picked;
                _notificationAppColorsSyncFromDom();
            }
        });
    });
}

export function notificationAddAppColor() {
    _notificationAppColorsSyncFromDom();
    _notificationAppColors.push({ app: '', color: '#ffffff' });
    _notificationAppColorsRenderList();
}

export function notificationRemoveAppColor(i: number) {
    _notificationAppColorsSyncFromDom();
    _notificationAppColors.splice(i, 1);
    _notificationAppColorsRenderList();
}

export async function testNotification(sourceId: string) {
    try {
        const resp = (await fetchWithAuth(`/color-strip-sources/${sourceId}/notify`, { method: 'POST' }))!;
        if (!resp.ok) {
            const err = await resp.json().catch(() => ({}));
            showToast(err.detail || t('color_strip.notification.test.error'), 'error');
            return;
        }
        const data = await resp.json();
        if (data.streams_notified > 0) {
            showToast(t('color_strip.notification.test.ok'), 'success');
        } else {
            showToast(t('color_strip.notification.test.no_streams'), 'warning');
        }
    } catch {
        showToast(t('color_strip.notification.test.error'), 'error');
    }
}

// ── OS Notification History Modal ─────────────────────────────────────────

export function showNotificationHistory() {
    const modal = document.getElementById('notification-history-modal') as HTMLElement | null;
    if (!modal) return;
    modal.style.display = 'flex';
    modal.onclick = (e) => { if (e.target === modal) closeNotificationHistory(); };
    _loadNotificationHistory();
}

export function closeNotificationHistory() {
    const modal = document.getElementById('notification-history-modal') as HTMLElement | null;
    if (modal) modal.style.display = 'none';
}

export async function refreshNotificationHistory() {
    await _loadNotificationHistory();
}

async function _loadNotificationHistory() {
    const list = document.getElementById('notification-history-list') as HTMLElement | null;
    const status = document.getElementById('notification-history-status') as HTMLElement | null;
    if (!list) return;

    try {
        const resp = (await fetchWithAuth('/color-strip-sources/os-notifications/history'))!;
        if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
        const data = await resp.json();

        if (!data.available) {
            list.innerHTML = '';
            if (status) {
                status.textContent = t('color_strip.notification.history.unavailable');
                status.style.display = '';
            }
            return;
        }

        if (status) status.style.display = 'none';

        const history = data.history || [];
        if (history.length === 0) {
            list.innerHTML = `<div class="notif-history-empty">${t('color_strip.notification.history.empty')}</div>`;
            return;
        }

        list.innerHTML = history.map((entry: any) => {
            const appName = entry.app || t('color_strip.notification.history.unknown_app');
            const timeStr = new Date(entry.time * 1000).toLocaleString();
            const fired = entry.fired ?? 0;
            const filtered = entry.filtered ?? 0;
            const firedBadge = fired > 0
                ? `<span class="notif-history-badge notif-history-badge--fired" title="${t('color_strip.notification.history.fired')}">${fired}</span>`
                : '';
            const filteredBadge = filtered > 0
                ? `<span class="notif-history-badge notif-history-badge--filtered" title="${t('color_strip.notification.history.filtered')}">${filtered}</span>`
                : '';
            return `<div class="notif-history-row">
                <div class="notif-history-app" title="${escapeHtml(appName)}">${escapeHtml(appName)}</div>
                <div class="notif-history-time">${timeStr}</div>
                <div class="notif-history-badges">${firedBadge}${filteredBadge}</div>
            </div>`;
        }).join('');
    } catch (err: any) {
        console.error('Failed to load notification history:', err);
        if (status) {
            status.textContent = t('color_strip.notification.history.error');
            status.style.display = '';
        }
        list.innerHTML = '';
    }
}

function _notificationAppColorsSyncFromDom() {
    const list = document.getElementById('notification-app-colors-list') as HTMLElement | null;
    if (!list) return;
    const names = list.querySelectorAll<HTMLInputElement>('.notif-app-name');
    const colors = list.querySelectorAll<HTMLInputElement>('.notif-app-color');
    if (names.length === _notificationAppColors.length) {
        for (let i = 0; i < names.length; i++) {
            _notificationAppColors[i].app = names[i].value;
            _notificationAppColors[i].color = colors[i].value;
        }
    }
}

export function notificationGetAppColorsDict() {
    _notificationAppColorsSyncFromDom();
    const dict: Record<string, any> = {};
    for (const entry of _notificationAppColors) {
        if (entry.app.trim()) dict[entry.app.trim()] = entry.color;
    }
    return dict;
}

export function loadNotificationState(css: any) {
    (document.getElementById('css-editor-notification-effect') as HTMLInputElement).value = css.notification_effect || 'flash';
    if (_notificationEffectIconSelect) _notificationEffectIconSelect.setValue(css.notification_effect || 'flash');
    const dur = css.duration_ms ?? 1500;
    (document.getElementById('css-editor-notification-duration') as HTMLInputElement).value = dur;
    (document.getElementById('css-editor-notification-duration-val') as HTMLElement).textContent = dur;
    (document.getElementById('css-editor-notification-default-color') as HTMLInputElement).value = css.default_color || '#ffffff';
    (document.getElementById('css-editor-notification-filter-mode') as HTMLInputElement).value = css.app_filter_mode || 'off';
    if (_notificationFilterModeIconSelect) _notificationFilterModeIconSelect.setValue(css.app_filter_mode || 'off');
    (document.getElementById('css-editor-notification-filter-list') as HTMLInputElement).value = (css.app_filter_list || []).join('\n');
    onNotificationFilterModeChange();
    _attachNotificationProcessPicker();

    // App colors dict -> list
    const ac = css.app_colors || {};
    _notificationAppColors = Object.entries(ac).map(([app, color]) => ({ app, color }));
    _notificationAppColorsRenderList();

    showNotificationEndpoint(css.id);
}

export function resetNotificationState() {
    (document.getElementById('css-editor-notification-effect') as HTMLInputElement).value = 'flash';
    if (_notificationEffectIconSelect) _notificationEffectIconSelect.setValue('flash');
    (document.getElementById('css-editor-notification-duration') as HTMLInputElement).value = 1500 as any;
    (document.getElementById('css-editor-notification-duration-val') as HTMLElement).textContent = '1500';
    (document.getElementById('css-editor-notification-default-color') as HTMLInputElement).value = '#ffffff';
    (document.getElementById('css-editor-notification-filter-mode') as HTMLInputElement).value = 'off';
    if (_notificationFilterModeIconSelect) _notificationFilterModeIconSelect.setValue('off');
    (document.getElementById('css-editor-notification-filter-list') as HTMLInputElement).value = '';
    onNotificationFilterModeChange();
    _attachNotificationProcessPicker();
    _notificationAppColors = [];
    _notificationAppColorsRenderList();
    showNotificationEndpoint(null);
}

function _attachNotificationProcessPicker() {
    const container = document.getElementById('css-editor-notification-filter-picker-container') as HTMLElement | null;
    const textarea = document.getElementById('css-editor-notification-filter-list') as HTMLTextAreaElement | null;
    if (container && textarea) attachNotificationAppPicker(container, textarea);
}

export function showNotificationEndpoint(cssId: any) {
    const el = document.getElementById('css-editor-notification-endpoint') as HTMLElement | null;
    if (!el) return;
    if (!cssId) {
        el.innerHTML = `<em data-i18n="color_strip.notification.save_first">${t('color_strip.notification.save_first')}</em>`;
        return;
    }
    const base = `${getBaseOrigin()}/api/v1`;
    const url = `${base}/color-strip-sources/${cssId}/notify`;
    el.innerHTML = `
        <small class="endpoint-label">POST</small>
        <div class="ws-url-row"><input type="text" value="${url}" readonly style="font-size:0.85em"><button type="button" class="btn btn-sm btn-secondary" onclick="copyEndpointUrl(this)" title="Copy">&#x1F4CB;</button></div>
    `;
}
