/**
 * Admin > System > Packages
 *
 * Full package lifecycle: list, install (upload + registry), enable/disable,
 * settings, export, delete.  Uses /api/v1/admin/packages endpoints.
 */
const { html } = window;
const { useState, useEffect, useCallback } = hooks;

const TYPE_OPTIONS = ['all', 'surface', 'extension', 'full', 'workflow'];
const CORE_IDS     = new Set(['admin']);

function typeBadge(type) {
    const cls = type === 'surface' ? 'badge-active'
              : type === 'extension' ? 'badge-pending' : '';
    return html`<span class="badge ${cls}">${type || '?'}</span>`;
}

function tierBadge(tier) {
    const cls = tier === 'browser' ? 'badge-active' : tier === 'starlark' ? 'badge-pending' : '';
    return html`<span class="badge ${cls}">${tier || 'unknown'}</span>`;
}

function sourceBadge(source) {
    if (!source || source === 'extension') return null;
    const cls = source === 'core' ? 'badge-active' : source === 'registry' ? 'badge-pending' : '';
    return html`<span class="badge ${cls}">${source}</span>`;
}

function statusBadge(status) {
    if (status === 'dormant') return html`<span class="badge" style="opacity:0.6;">dormant</span>`;
    return null;
}

export default function PackagesSection() {
    const [packages, setPackages]           = useState([]);
    const [loading, setLoading]             = useState(true);
    const [typeFilter, setTypeFilter]       = useState('all');
    const [expandedId, setExpandedId]       = useState(null);
    const [pkgSettings, setPkgSettings]     = useState(null);
    const [settingsDraft, setSettingsDraft] = useState({});
    const [registryOpen, setRegistryOpen]   = useState(false);
    const [registryPkgs, setRegistryPkgs]   = useState([]);
    const [registryLoading, setRegistryLoading] = useState(false);
    const [installing, setInstalling]       = useState(false);

    const BASE = window.__BASE__ || '';

    // ── Load packages ───────────────────────────
    const load = useCallback(async () => {
        try {
            const opts = typeFilter !== 'all' ? { type: typeFilter } : undefined;
            const data = await sw.api.admin.packages.list(opts);
            setPackages(data || []);
        } catch (e) { sw.toast(e.message, 'error'); }
        finally { setLoading(false); }
    }, [typeFilter]);

    useEffect(() => { setLoading(true); load(); }, [typeFilter]);

    // ── Actions ─────────────────────────────────
    async function toggleEnabled(pkg) {
        if (CORE_IDS.has(pkg.id)) return;
        if (pkg.status === 'dormant') {
            sw.toast('This package requires chat — it cannot be enabled yet', 'error');
            return;
        }
        try {
            if (pkg.enabled) {
                await sw.api.admin.packages.disable(pkg.id);
                sw.toast(`${pkg.title || pkg.id} disabled`, 'success');
            } else {
                await sw.api.admin.packages.enable(pkg.id);
                sw.toast(`${pkg.title || pkg.id} enabled`, 'success');
            }
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function deletePkg(pkg) {
        if (pkg.source === 'core') return;
        const ok = await sw.confirm(`Delete "${pkg.title || pkg.id}"? This cannot be undone.`, true);
        if (!ok) return;
        try {
            await sw.api.admin.packages.del(pkg.id);
            sw.toast('Package deleted', 'success');
            if (expandedId === pkg.id) { setExpandedId(null); setPkgSettings(null); }
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    function uploadPackage() {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.pkg,.surface,.zip';
        input.onchange = async () => {
            const file = input.files[0];
            if (!file) return;
            setInstalling(true);
            try {
                await sw.api.admin.packages.install(file);
                sw.toast('Package installed', 'success');
                load();
            } catch (e) { sw.toast(e.message, 'error'); }
            finally { setInstalling(false); }
        };
        input.click();
    }

    function exportPkg(id) {
        window.open(`${BASE}/api/v1/admin/packages/${id}/export`, '_blank');
    }

    // ── Settings drawer ─────────────────────────
    async function toggleSettings(pkgId) {
        if (expandedId === pkgId) {
            setExpandedId(null); setPkgSettings(null); setSettingsDraft({});
            return;
        }
        try {
            const data = await sw.api.admin.packages.settings(pkgId);
            const settings = data?.data || {};
            setPkgSettings(settings);
            setSettingsDraft({ ...settings });
            setExpandedId(pkgId);
        } catch (e) {
            sw.toast(e.message, 'error');
        }
    }

    async function saveSettings(pkgId) {
        try {
            await sw.api.admin.packages.updateSettings(pkgId, settingsDraft);
            sw.toast('Settings saved', 'success');
            setPkgSettings({ ...settingsDraft });
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    // ── Registry ────────────────────────────────
    async function toggleRegistry() {
        if (registryOpen) { setRegistryOpen(false); return; }
        setRegistryOpen(true);
        setRegistryLoading(true);
        try {
            const data = await sw.api.admin.packages.registry();
            setRegistryPkgs(data?.data || []);
        } catch (e) {
            sw.toast('Registry unavailable: ' + e.message, 'error');
            setRegistryPkgs([]);
        }
        finally { setRegistryLoading(false); }
    }

    async function installFromRegistry(url) {
        try {
            await sw.api.admin.packages.registryInstall(url);
            sw.toast('Package installed from registry', 'success');
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    // ── Render ───────────────────────────────────
    if (loading) return html`<div class="settings-placeholder">Loading\u2026</div>`;

    const enabled = packages.filter(p => p.enabled).length;
    const dormant = packages.filter(p => p.status === 'dormant').length;
    const hasManifestSettings = (pkg) =>
        pkg.manifest?.settings || pkg.package_settings;

    return html`
        <div>
            ${/* ── Stat cards ─────────────── */``}
            <div class="stat-cards-grid" style="margin-bottom:16px;">
                <div class="stat-card"><div class="stat-value">${packages.length}</div><div class="stat-label">Total</div></div>
                <div class="stat-card"><div class="stat-value">${enabled}</div><div class="stat-label">Enabled</div></div>
                ${dormant > 0 && html`<div class="stat-card"><div class="stat-value">${dormant}</div><div class="stat-label">Dormant</div></div>`}
            </div>

            ${/* ── Action bar ─────────────── */``}
            <div style="display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:14px;">
                ${TYPE_OPTIONS.map(t => html`
                    <button key=${t}
                        class="btn-small ${typeFilter === t ? 'btn-primary' : ''}"
                        onClick=${() => setTypeFilter(t)}
                        style="text-transform:capitalize;">${t}</button>
                `)}
                <span style="flex:1;" />
                <button class="btn-small" onClick=${uploadPackage} disabled=${installing}>
                    ${installing ? 'Installing\u2026' : 'Install Package'}
                </button>
                <button class="btn-small" onClick=${toggleRegistry}>
                    ${registryOpen ? 'Close Registry' : 'Browse Registry'}
                </button>
            </div>

            ${/* ── Package list ────────────── */``}
            <div class="admin-list">
                ${packages.length === 0 && html`<div class="empty-hint">No packages found</div>`}
                ${packages.map(pkg => html`
                    <div key=${pkg.id}>
                        <div class="admin-surface-row">
                            <div style="flex:1;min-width:0;">
                                <strong>${pkg.title || pkg.id}</strong>
                                <span class="text-muted" style="margin-left:6px;font-size:11px;">v${pkg.version || '?'}</span>
                                ${' '}${typeBadge(pkg.type)}
                                ${' '}${tierBadge(pkg.tier)}
                                ${sourceBadge(pkg.source)}
                                ${statusBadge(pkg.status)}
                                ${pkg.is_system && html`<span class="badge" style="margin-left:4px;">system</span>`}
                            </div>
                            <div class="admin-actions-cell">
                                <button class="btn-small"
                                    onClick=${() => toggleEnabled(pkg)}
                                    disabled=${CORE_IDS.has(pkg.id) || pkg.status === 'dormant'}
                                    title=${pkg.status === 'dormant' ? 'Requires chat' : ''}>
                                    ${pkg.enabled ? 'Disable' : 'Enable'}
                                </button>
                                ${hasManifestSettings(pkg) && html`
                                    <button class="btn-small" onClick=${() => toggleSettings(pkg.id)}>
                                        ${expandedId === pkg.id ? 'Close' : 'Settings'}
                                    </button>
                                `}
                                <button class="btn-small" onClick=${() => exportPkg(pkg.id)}>Export</button>
                                ${pkg.source !== 'core' && !pkg.is_system && html`
                                    <button class="btn-small btn-danger" onClick=${() => deletePkg(pkg)}>Delete</button>
                                `}
                            </div>
                        </div>

                        ${/* ── Inline settings drawer ── */``}
                        ${expandedId === pkg.id && pkgSettings != null && html`
                            <div style="padding:8px 12px 12px 24px;background:var(--bg-2);border-bottom:1px solid var(--border);">
                                ${Object.keys(pkgSettings).length === 0
                                    ? html`<span class="text-muted" style="font-size:12px;">No configurable settings</span>`
                                    : html`
                                        ${Object.entries(settingsDraft).map(([k, v]) => html`
                                            <div key=${k} style="display:flex;gap:8px;align-items:center;margin-bottom:6px;">
                                                <label style="min-width:120px;font-size:12px;color:var(--text-muted);">${k}</label>
                                                <input type="text"
                                                    value=${v ?? ''}
                                                    onInput=${e => setSettingsDraft(prev => ({ ...prev, [k]: e.target.value }))}
                                                    style="flex:1;padding:4px 8px;background:var(--bg-1,var(--bg));color:var(--text);border:1px solid var(--border);border-radius:4px;font-size:12px;" />
                                            </div>
                                        `)}
                                        <button class="btn-small" style="margin-top:4px;" onClick=${() => saveSettings(pkg.id)}>Save</button>
                                    `
                                }
                            </div>
                        `}
                    </div>
                `)}
            </div>

            ${/* ── Registry panel ──────────── */``}
            ${registryOpen && html`
                <div class="admin-section" style="margin-top:20px;padding:12px;border:1px solid var(--border);border-radius:6px;">
                    <h4 style="margin:0 0 8px;">Package Registry</h4>
                    ${registryLoading
                        ? html`<div class="settings-placeholder">Loading registry\u2026</div>`
                        : registryPkgs.length === 0
                            ? html`<div class="empty-hint">No packages available in registry</div>`
                            : html`
                                <div class="admin-list">
                                    ${registryPkgs.map(rp => html`
                                        <div class="admin-surface-row" key=${rp.id}>
                                            <div style="flex:1;min-width:0;">
                                                <strong>${rp.title || rp.id}</strong>
                                                <span class="text-muted" style="margin-left:6px;font-size:11px;">v${rp.version || '?'}</span>
                                                ${rp.description && html`
                                                    <div class="text-muted" style="font-size:11px;margin-top:2px;">${rp.description}</div>
                                                `}
                                            </div>
                                            <div class="admin-actions-cell">
                                                ${typeBadge(rp.type)}
                                                <button class="btn-small btn-primary"
                                                    onClick=${() => installFromRegistry(rp.download_url)}>Install</button>
                                            </div>
                                        </div>
                                    `)}
                                </div>
                            `
                    }
                </div>
            `}
        </div>
    `;
}
