// templates_options/templates_options.js

const TEMPLATE_STORAGE_KEY = 'message_templates';
const HASH_STORAGE_KEY = 'sync_hashes';
const SYNC_CONFIG_KEY = 'gitea_config';
const SIG_SOURCE_KEY = 'sig_source_map';
const SIG_FOOTER_KEY = 'sig_footer_cache';

// ── Toast, Modal, Offline, Token Toggle ──

function showToast(message, type = 'info', duration = 4000) {
    const container = document.getElementById('toast-container');
    const toast = document.createElement('div');
    toast.className = `toast toast-${type}`;
    toast.textContent = message;
    container.appendChild(toast);
    setTimeout(() => {
        toast.classList.add('toast-out');
        setTimeout(() => toast.remove(), 300);
    }, duration);
}

function showConfirmDialog(title, message, confirmText = 'Löschen') {
    return new Promise(resolve => {
        const modal = document.getElementById('confirm-modal');
        document.getElementById('modal-title').textContent = title;
        document.getElementById('modal-message').textContent = message;
        document.getElementById('modal-confirm').textContent = confirmText;
        modal.classList.add('open');

        function cleanup(result) {
            modal.classList.remove('open');
            document.getElementById('modal-confirm').removeEventListener('click', onConfirm);
            document.getElementById('modal-cancel').removeEventListener('click', onCancel);
            resolve(result);
        }
        function onConfirm() { cleanup(true); }
        function onCancel() { cleanup(false); }
        document.getElementById('modal-confirm').addEventListener('click', onConfirm);
        document.getElementById('modal-cancel').addEventListener('click', onCancel);
    });
}

function checkOnline() {
    if (!navigator.onLine) {
        showToast('Keine Internetverbindung – Synchronisation nicht möglich.', 'error', 5000);
        return false;
    }
    return true;
}

window.addEventListener('online', () => {
    document.getElementById('offline-banner').classList.remove('visible');
    showToast('Wieder online.', 'success', 2000);
});
window.addEventListener('offline', () => {
    document.getElementById('offline-banner').classList.add('visible');
});

// Token toggle + name validation
document.addEventListener('DOMContentLoaded', () => {
    const toggle = document.getElementById('token-toggle');
    if (toggle) {
        toggle.addEventListener('click', () => {
            const input = document.getElementById('sync-token');
            const icon = toggle.querySelector('.mdi');
            if (input.type === 'password') {
                input.type = 'text';
                icon.className = 'mdi mdi-eye-off';
            } else {
                input.type = 'password';
                icon.className = 'mdi mdi-eye';
            }
        });
    }

    // Template name inline validation
    const nameInput = document.getElementById('template-name');
    if (nameInput) {
        nameInput.addEventListener('input', async () => {
            const val = nameInput.value.trim();
            nameInput.classList.remove('input-error', 'input-valid');
            const msgEl = nameInput.parentElement.querySelector('.validation-msg');
            if (msgEl) msgEl.remove();

            if (!val) {
                nameInput.classList.add('input-error');
                nameInput.insertAdjacentHTML('afterend', '<span class="validation-msg error">Bitte Titel eingeben</span>');
                return;
            }

            const templates = await getTemplates();
            const editId = document.getElementById('template-id').value;
            const duplicate = templates.find(t => t.name.toLowerCase() === val.toLowerCase() && t.id !== editId);
            if (duplicate) {
                nameInput.classList.add('input-error');
                nameInput.insertAdjacentHTML('afterend', '<span class="validation-msg error">Titel bereits vergeben</span>');
            } else {
                nameInput.classList.add('input-valid');
            }
        });
    }
});

// ── Cached author email (for personal folder path) ──
let cachedAuthorEmail = '';

async function getAuthorEmail() {
    if (cachedAuthorEmail) return cachedAuthorEmail;
    const result = await browser.storage.local.get(SYNC_CONFIG_KEY);
    cachedAuthorEmail = result[SYNC_CONFIG_KEY]?.authorEmail || '';
    return cachedAuthorEmail;
}

// ── DOM Elements ──

const editorPanel = document.getElementById('tpl-editor-panel');
const templateForm = document.getElementById('template-form');
const templateList = document.getElementById('templates-list');
const noTemplatesMessage = document.getElementById('no-templates');
const saveButton = document.getElementById('save-button');
const cancelButton = document.getElementById('cancel-edit');
const formLegend = document.getElementById('form-legend');
const editorArea = document.getElementById('editor-area');

const sigIdentitySelect = document.getElementById('sig-identity-select');
const sigEditorArea = document.getElementById('sig-editor-area');
const sigSourceSelect = document.getElementById('sig-source-select');
const sigSourceInfo = document.getElementById('sig-source-info');

// ── System Font Detection ──

const FONT_CANDIDATES = [
    'Arial', 'Arial Black', 'Arial Narrow', 'Book Antiqua', 'Bookman Old Style',
    'Calibri', 'Cambria', 'Candara', 'Century Gothic', 'Comic Sans MS',
    'Consolas', 'Constantia', 'Corbel', 'Courier New', 'DejaVu Sans',
    'DejaVu Sans Mono', 'DejaVu Serif', 'Droid Sans', 'Droid Serif',
    'Franklin Gothic Medium', 'Garamond', 'Georgia', 'Gill Sans',
    'Helvetica', 'Helvetica Neue', 'Impact', 'Liberation Mono',
    'Liberation Sans', 'Liberation Serif', 'Lucida Console',
    'Lucida Sans Unicode', 'Microsoft Sans Serif', 'Monaco', 'Noto Sans',
    'Noto Serif', 'Open Sans', 'Palatino Linotype', 'Roboto', 'Segoe UI',
    'Source Sans Pro', 'Tahoma', 'Times New Roman', 'Trebuchet MS',
    'Ubuntu', 'Verdana'
];

const availableFonts = FONT_CANDIDATES.filter(f => document.fonts.check(`12px "${f}"`));

const fontInput = document.getElementById('font-input');
const fontDropdown = document.getElementById('font-dropdown');

function renderFontDropdown(filter) {
    fontDropdown.innerHTML = '';
    const q = (filter || '').toLowerCase();
    const matches = q ? availableFonts.filter(f => f.toLowerCase().includes(q)) : availableFonts;

    for (const font of matches) {
        const div = document.createElement('div');
        div.className = 'font-option';
        div.textContent = font;
        div.style.fontFamily = font;
        div.addEventListener('mousedown', (e) => {
            e.preventDefault();
            fontInput.value = '';
            fontDropdown.classList.remove('open');
            editorArea.focus();
            document.execCommand('fontName', false, font);
        });
        fontDropdown.appendChild(div);
    }
    const isOpen = matches.length > 0;
    fontDropdown.classList.toggle('open', isOpen);
    if (isOpen) {
        requestAnimationFrame(() => {
            const rect = fontDropdown.getBoundingClientRect();
            if (rect.bottom > window.innerHeight) {
                fontDropdown.style.top = 'auto';
                fontDropdown.style.bottom = '100%';
            } else {
                fontDropdown.style.top = '100%';
                fontDropdown.style.bottom = 'auto';
            }
        });
    }
}

fontInput.addEventListener('focus', () => renderFontDropdown(fontInput.value));
fontInput.addEventListener('input', () => renderFontDropdown(fontInput.value));
fontInput.addEventListener('blur', () => setTimeout(() => fontDropdown.classList.remove('open'), 150));
fontInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
        e.preventDefault();
        const font = fontInput.value.trim();
        if (!font) return;
        fontInput.value = '';
        fontDropdown.classList.remove('open');
        editorArea.focus();
        document.execCommand('fontName', false, font);
    }
});

// ── Editor Helpers ──

function getEditorContent() {
    const html = editorArea.innerHTML;
    return (!html || html === '<br>') ? '' : html;
}

function setEditorContent(html) {
    editorArea.innerHTML = html || '';
}

// ── Toolbar Commands (template editor) ──

function setupToolbarCommands(toolbarId, targetEditor) {
    document.querySelectorAll(`#${toolbarId} button[data-cmd]`).forEach(btn => {
        btn.addEventListener('click', () => {
            targetEditor.focus();
            const cmd = btn.dataset.cmd;
            let val = btn.dataset.val || null;

            if (val === 'ask') {
                if (cmd === 'createLink') {
                    val = prompt('Link-URL eingeben:', 'https://');
                    if (!val) return;
                } else if (cmd === 'foreColor' || cmd === 'hiliteColor') {
                    const colorInput = document.createElement('input');
                    colorInput.type = 'color';
                    colorInput.value = cmd === 'foreColor' ? '#000000' : '#ffff00';
                    colorInput.addEventListener('input', () => {
                        targetEditor.focus();
                        document.execCommand(cmd, false, colorInput.value);
                    });
                    colorInput.click();
                    return;
                }
            }
            document.execCommand(cmd, false, val);
        });
    });

    const fontSizeSelect = document.querySelector(`#${toolbarId} select[data-cmd="fontSize"]`);
    if (fontSizeSelect) {
        fontSizeSelect.addEventListener('change', function() {
            if (!this.value) return;
            targetEditor.focus();
            document.execCommand('fontSize', false, this.value);
            this.value = '';
        });
    }
}

setupToolbarCommands('tpl-toolbar', editorArea);
setupToolbarCommands('sig-toolbar', sigEditorArea);

// ── Signature Font Combo ──

const sigFontInput = document.getElementById('sig-font-input');
const sigFontDropdown = document.getElementById('sig-font-dropdown');

function renderSigFontDropdown(filter) {
    sigFontDropdown.innerHTML = '';
    const q = (filter || '').toLowerCase();
    const matches = q ? availableFonts.filter(f => f.toLowerCase().includes(q)) : availableFonts;

    for (const font of matches) {
        const div = document.createElement('div');
        div.className = 'font-option';
        div.textContent = font;
        div.style.fontFamily = font;
        div.addEventListener('mousedown', (e) => {
            e.preventDefault();
            sigFontInput.value = '';
            sigFontDropdown.classList.remove('open');
            sigEditorArea.focus();
            document.execCommand('fontName', false, font);
        });
        sigFontDropdown.appendChild(div);
    }
    const isOpen = matches.length > 0;
    sigFontDropdown.classList.toggle('open', isOpen);
    if (isOpen) {
        requestAnimationFrame(() => {
            const rect = sigFontDropdown.getBoundingClientRect();
            if (rect.bottom > window.innerHeight) {
                sigFontDropdown.style.top = 'auto';
                sigFontDropdown.style.bottom = '100%';
            } else {
                sigFontDropdown.style.top = '100%';
                sigFontDropdown.style.bottom = 'auto';
            }
        });
    }
}

sigFontInput.addEventListener('focus', () => renderSigFontDropdown(sigFontInput.value));
sigFontInput.addEventListener('input', () => renderSigFontDropdown(sigFontInput.value));
sigFontInput.addEventListener('blur', () => setTimeout(() => sigFontDropdown.classList.remove('open'), 150));
sigFontInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
        e.preventDefault();
        const font = sigFontInput.value.trim();
        if (!font) return;
        sigFontInput.value = '';
        sigFontDropdown.classList.remove('open');
        sigEditorArea.focus();
        document.execCommand('fontName', false, font);
    }
});

// ── Image Insert ──

function setupImageInsert(buttonId, fileInputId, editorEl) {
    document.getElementById(buttonId).addEventListener('click', () => {
        document.getElementById(fileInputId).click();
    });
    document.getElementById(fileInputId).addEventListener('change', (e) => {
        const file = e.target.files[0];
        if (!file) return;
        const reader = new FileReader();
        reader.onload = () => {
            editorEl.focus();
            document.execCommand('insertImage', false, reader.result);
        };
        reader.readAsDataURL(file);
        e.target.value = '';
    });
}

setupImageInsert('tpl-insert-image', 'tpl-image-file', editorArea);
setupImageInsert('sig-insert-image', 'sig-image-file', sigEditorArea);

// ── Tab Navigation ──

document.querySelectorAll('.tab-btn').forEach(btn => {
    btn.addEventListener('click', () => {
        document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
        document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
        btn.classList.add('active');
        document.getElementById('tab-' + btn.dataset.tab).classList.add('active');
    });
});

// ── Collapsible Import ──

document.getElementById('import-toggle').addEventListener('click', function() {
    this.classList.toggle('open');
    document.getElementById('import-body').classList.toggle('open');
});

// ── Template Storage ──

async function getTemplates() {
    try {
        const result = await browser.storage.local.get(TEMPLATE_STORAGE_KEY);
        return result[TEMPLATE_STORAGE_KEY] || [];
    } catch (error) {
        console.error("Error retrieving templates:", error);
        return [];
    }
}

async function saveTemplates(templates) {
    await browser.storage.local.set({ [TEMPLATE_STORAGE_KEY]: templates });
}

// ── Sync Status Tracking ──

let tplSyncedHashes = {};
let sigSyncedHashes = {};
let lastPulledShas = {};
let currentRemoteShas = {};
let allIdentities = [];

function simpleHash(str) {
    let h = 0;
    for (let i = 0; i < str.length; i++) {
        h = ((h << 5) - h + str.charCodeAt(i)) | 0;
    }
    return h;
}

async function loadSyncHashes() {
    try {
        const result = await browser.storage.local.get(HASH_STORAGE_KEY);
        const data = result[HASH_STORAGE_KEY] || {};
        tplSyncedHashes = data.tpl || {};
        sigSyncedHashes = data.sig || {};
        lastPulledShas = data.remoteShas || {};
        currentRemoteShas = { ...lastPulledShas };
    } catch (_) {}
}

async function saveSyncHashes() {
    await browser.storage.local.set({
        [HASH_STORAGE_KEY]: { tpl: tplSyncedHashes, sig: sigSyncedHashes, remoteShas: lastPulledShas }
    });
}

function hasServerUpdate(template) {
    if (!template.remotePath) return false;
    const pulled = lastPulledShas[template.remotePath];
    const remote = currentRemoteShas[template.remotePath];
    if (!pulled || !remote) return false;
    return pulled !== remote;
}

async function checkForServerUpdates() {
    try {
        const result = await browser.runtime.sendMessage({ action: 'checkRemoteShas' });
        if (result && result.success) {
            currentRemoteShas = result.remoteShas;
            const templates = await getTemplates();
            renderTemplates(templates);
            updateTplSyncIndicator();
        }
    } catch (_) {}
}

function storeTplHashes(templates) {
    tplSyncedHashes = {};
    for (const t of templates) {
        tplSyncedHashes[t.id] = simpleHash(t.content || '');
    }
    lastPulledShas = { ...currentRemoteShas };
    saveSyncHashes();
}

function getTplSyncClass(template) {
    if (tplSyncedHashes[template.id] === undefined) return 'unknown';
    return simpleHash(template.content || '') === tplSyncedHashes[template.id] ? 'in-sync' : 'out-of-sync';
}

function updateTplSyncIndicator() {
    const el = document.getElementById('tpl-sync-indicator');
    if (!el) return;
    const dot = el.querySelector('.sync-dot');
    const label = el.querySelector('span:last-child');

    if (Object.keys(tplSyncedHashes).length === 0) {
        dot.className = 'sync-dot unknown';
        label.textContent = 'Sync-Status unbekannt';
        return;
    }

    getTemplates().then(templates => {
        const outOfSync = templates.filter(t => getTplSyncClass(t) === 'out-of-sync').length;
        const unknown = templates.filter(t => getTplSyncClass(t) === 'unknown').length;
        if (outOfSync > 0) {
            dot.className = 'sync-dot out-of-sync';
            label.textContent = `${outOfSync} Vorlage(n) nicht hochgeladen`;
        } else if (unknown > 0) {
            dot.className = 'sync-dot unknown';
            label.textContent = `${unknown} Vorlage(n) unbekannt`;
        } else {
            dot.className = 'sync-dot in-sync';
            label.textContent = 'Alle Vorlagen synchron';
        }
    });
}

function updateSigSyncIndicator() {
    const el = document.getElementById('sig-sync-indicator');
    if (!el) return;
    const dot = el.querySelector('.sync-dot');
    const label = el.querySelector('span:last-child');

    if (Object.keys(sigSyncedHashes).length === 0) {
        dot.className = 'sync-dot unknown';
        label.textContent = 'Sync-Status unbekannt';
        return;
    }

    let outOfSync = 0;
    for (const identity of allIdentities) {
        const email = identity.email.toLowerCase();
        if (sigSyncedHashes[email] !== undefined) {
            if (simpleHash(identity.signature || '') !== sigSyncedHashes[email]) {
                outOfSync++;
            }
        }
    }

    if (outOfSync > 0) {
        dot.className = 'sync-dot out-of-sync';
        label.textContent = `${outOfSync} Signatur(en) nicht hochgeladen`;
    } else {
        dot.className = 'sync-dot in-sync';
        label.textContent = 'Alle Signaturen synchron';
    }
}

// ── Template List Rendering ──

function renderTemplates(templates) {
    templateList.innerHTML = '';

    if (templates.length === 0) {
        templateList.appendChild(noTemplatesMessage);
        noTemplatesMessage.style.display = 'block';
        return;
    }
    noTemplatesMessage.style.display = 'none';

    templates.forEach(template => {
        const item = document.createElement('div');
        item.className = 'template-item';
        const syncClass = getTplSyncClass(template);
        const scopeValue = template.folder === '_gemeinsam' ? 'shared'
            : template.folder?.startsWith('_benutzer/') ? 'private' : 'department';
        const badgeClass = scopeValue === 'shared' ? 'badge-shared'
            : scopeValue === 'department' ? 'badge-dept' : 'badge-private';
        const folderBadge = `<select class="scope-select ${badgeClass}" data-id="${template.id}">
            <option value="private" ${scopeValue === 'private' ? 'selected' : ''}>Persönlich</option>
            <option value="department" ${scopeValue === 'department' ? 'selected' : ''}>${document.getElementById('sync-department')?.value || 'Abteilung'}</option>
            <option value="shared" ${scopeValue === 'shared' ? 'selected' : ''}>Alle</option>
        </select>`;
        const pushBtn = syncClass === 'out-of-sync'
            ? `<button data-id="${template.id}" class="push-btn" title="Diese Vorlage hochladen">⬆ Hochladen</button>`
            : '';
        const pullBtn = hasServerUpdate(template)
            ? `<button data-id="${template.id}" class="pull-btn" title="Neuere Version vom Server laden">⬇ Laden</button>`
            : '';
        item.innerHTML = `
            <span class="sync-dot ${syncClass}" title="${syncClass === 'in-sync' ? 'Synchron' : syncClass === 'out-of-sync' ? 'Nicht hochgeladen' : 'Unbekannt'}" aria-label="${syncClass === 'in-sync' ? 'Synchron' : syncClass === 'out-of-sync' ? 'Nicht hochgeladen' : 'Unbekannt'}"></span>
            <label class="template-label"><input type="checkbox" class="template-checkbox" data-id="${template.id}"><span class="template-name">${template.name}</span>${folderBadge}</label>
            <div class="template-actions">
                ${pullBtn}${pushBtn}
                <button data-id="${template.id}" class="edit-btn">Bearbeiten</button>
                <button data-id="${template.id}" class="delete-btn">Löschen</button>
            </div>
        `;
        templateList.appendChild(item);
    });

    document.querySelectorAll('.edit-btn').forEach(b => b.addEventListener('click', handleEdit));
    document.querySelectorAll('.delete-btn').forEach(b => b.addEventListener('click', handleDelete));
    document.querySelectorAll('.push-btn').forEach(b => b.addEventListener('click', handlePushSingle));
    document.querySelectorAll('.pull-btn').forEach(b => b.addEventListener('click', handlePullSingle));
    document.querySelectorAll('.scope-select').forEach(sel => sel.addEventListener('change', handleScopeChange));
}

// ── Inline Editor Panel ──

function openEditorPanel() {
    editorPanel.classList.add('open');
    // Update department name in scope dropdown
    const deptName = document.getElementById('sync-department')?.value || 'Abteilung';
    const deptOption = document.querySelector('#tpl-scope-select option[value="department"]');
    if (deptOption) deptOption.textContent = deptName;
    editorPanel.scrollIntoView({ behavior: 'smooth', block: 'start' });
}

function closeEditorPanel() {
    editorPanel.classList.remove('open');
    templateForm.reset();
    document.getElementById('template-id').value = '';
    setEditorContent('');
    formLegend.textContent = 'Neue Vorlage erstellen';
    saveButton.textContent = 'Speichern';
}

document.getElementById('new-template-button').addEventListener('click', () => {
    closeEditorPanel();
    document.getElementById('tpl-scope-select').value = 'private';
    formLegend.textContent = 'Neue Vorlage erstellen';
    saveButton.textContent = 'Speichern';
    openEditorPanel();
});

cancelButton.addEventListener('click', closeEditorPanel);

// ── Form Submit (Add/Edit) ──

templateForm.addEventListener('submit', async (e) => {
    e.preventDefault();
    const id = document.getElementById('template-id').value;
    const name = document.getElementById('template-name').value;
    const content = getEditorContent();

    if (!content.trim()) {
        showToast('Bitte Inhalt eingeben.', 'error');
        return;
    }

    let templates = await getTemplates();

    const scope = document.getElementById('tpl-scope-select').value;
    const authorEmail = await getAuthorEmail();
    let folder;
    if (scope === 'shared') folder = '_gemeinsam';
    else if (scope === 'private') folder = `_benutzer/${authorEmail}`;
    else folder = undefined; // department — pushTemplates sets this.department

    if (scope === 'private' && !authorEmail) {
        showToast('Bitte E-Mail in den Einstellungen eintragen für persönliche Vorlagen.', 'error');
        return;
    }

    if (id) {
        const index = templates.findIndex(t => t.id === id);
        if (index > -1) {
            const existingTemplate = templates[index];
            const oldFolder = existingTemplate.folder;
            const scopeChanged = oldFolder !== folder;

            // Handle scope change: delete old remote file if needed
            if (scopeChanged && existingTemplate.remotePath) {
                const isDowngrade = (oldFolder === '_gemeinsam' && folder !== '_gemeinsam') ||
                    (!oldFolder?.startsWith('_benutzer/') && folder?.startsWith('_benutzer/'));

                if (isDowngrade) {
                    const confirmed = await showConfirmDialog(
                        'Sichtbarkeit verringern?',
                        'Die Vorlage wird am bisherigen Ort gelöscht. Andere Nutzer verlieren ggf. den Zugriff.',
                        'Trotzdem ändern'
                    );
                    if (!confirmed) return;
                }
                try {
                    await browser.runtime.sendMessage({
                        action: 'deleteRemoteTemplate',
                        remotePath: existingTemplate.remotePath
                    });
                } catch (_) {}
                existingTemplate.remotePath = undefined;
            }

            templates[index] = { id, name, content, folder, remotePath: existingTemplate.remotePath };
        }
    } else {
        templates.push({ id: Date.now().toString(), name, content, folder });
    }

    await saveTemplates(templates);
    renderTemplates(templates);
    closeEditorPanel();
    updateTplSyncIndicator();

    // Auto-push to server
    try {
        await browser.runtime.sendMessage({ action: 'pushTemplates' });
        const freshTemplates = await getTemplates();
        await checkForServerUpdates();
        storeTplHashes(freshTemplates);
        renderTemplates(freshTemplates);
        updateTplSyncIndicator();
    } catch (_) {}
});

// ── Edit / Delete / Push / Pull ──

async function handleEdit(e) {
    const idToEdit = e.target.dataset.id;
    const templates = await getTemplates();
    const template = templates.find(t => t.id === idToEdit);
    if (!template) return;

    document.getElementById('template-id').value = template.id;
    document.getElementById('template-name').value = template.name;
    const scopeSelect = document.getElementById('tpl-scope-select');
    if (template.folder === '_gemeinsam') scopeSelect.value = 'shared';
    else if (template.folder?.startsWith('_benutzer/')) scopeSelect.value = 'private';
    else scopeSelect.value = 'department';
    setEditorContent(template.content);
    formLegend.textContent = 'Vorlage bearbeiten';
    saveButton.textContent = 'Aktualisieren';
    openEditorPanel();
}

async function handleDelete(e) {
    const id = e.target.dataset.id;
    let templates = await getTemplates();
    const template = templates.find(t => t.id === id);
    if (!template) return;

    if (template.remotePath) {
        const confirmed = await showConfirmDialog(
            `"${template.name}" löschen?`,
            'Die Vorlage wird lokal und vom Server gelöscht (für alle Nutzer).',
            'Überall löschen'
        );
        if (!confirmed) return;

        // Delete from server
        try {
            const result = await browser.runtime.sendMessage({
                action: 'deleteRemoteTemplate',
                remotePath: template.remotePath
            });
            if (!result?.success) {
                showToast('Fehler beim Löschen vom Server: ' + (result?.error || 'Unbekannt'), 'error', 6000);
            }
        } catch (err) {
            showToast('Fehler beim Löschen vom Server: ' + err.message, 'error', 6000);
        }
    } else {
        const confirmed = await showConfirmDialog(
            'Vorlage löschen?',
            `"${template.name}" wirklich löschen?`
        );
        if (!confirmed) return;
    }

    templates = templates.filter(t => t.id !== id);
    await saveTemplates(templates);
    renderTemplates(templates);
    updateTplSyncIndicator();
    showToast('Vorlage gelöscht.', 'info');
}

async function handlePullSingle(e) {
    const btn = e.target.closest('.pull-btn') || e.target;
    const id = btn.dataset.id;
    const templates = await getTemplates();
    const template = templates.find(t => t.id === id);
    if (!template || !template.remotePath) return;
    if (!checkOnline()) return;

    const origHTML = btn.innerHTML;
    btn.innerHTML = '<span class="spinner"></span>';
    btn.disabled = true;

    try {
        const result = await browser.runtime.sendMessage({
            action: 'pullSingleTemplate',
            remotePath: template.remotePath
        });
        if (result && result.success) {
            template.content = result.content;
            await saveTemplates(templates);
            tplSyncedHashes[id] = simpleHash(result.content || '');
            if (template.remotePath && currentRemoteShas[template.remotePath]) {
                lastPulledShas[template.remotePath] = currentRemoteShas[template.remotePath];
            }
            saveSyncHashes();
            renderTemplates(templates);
            updateTplSyncIndicator();
            showToast('Vorlage heruntergeladen.', 'success');
        } else {
            showToast('Fehler: ' + (result?.error || 'Unbekannt'), 'error', 6000);
            btn.innerHTML = origHTML;
            btn.disabled = false;
        }
    } catch (err) {
        showToast('Fehler: ' + err.message, 'error', 6000);
        btn.innerHTML = origHTML;
        btn.disabled = false;
    }
}

async function handlePushSingle(e) {
    const btn = e.target.closest('.push-btn') || e.target;
    const id = btn.dataset.id;
    const templates = await getTemplates();
    const template = templates.find(t => t.id === id);
    if (!template) return;
    if (!checkOnline()) return;

    const origHTML = btn.innerHTML;
    btn.innerHTML = '<span class="spinner"></span>';
    btn.disabled = true;

    try {
        const result = await browser.runtime.sendMessage({
            action: 'pushSingleTemplate',
            templateId: id
        });
        if (result && result.success) {
            tplSyncedHashes[id] = simpleHash(template.content || '');
            saveSyncHashes();
            renderTemplates(templates);
            updateTplSyncIndicator();
            showToast('Vorlage hochgeladen.', 'success');
        } else {
            showToast('Fehler: ' + (result?.error || 'Unbekannt'), 'error', 6000);
            btn.innerHTML = origHTML;
            btn.disabled = false;
        }
    } catch (err) {
        showToast('Fehler: ' + err.message, 'error', 6000);
        btn.innerHTML = origHTML;
        btn.disabled = false;
    }
}

// ── Inline Scope Change ──

function folderToScope(folder) {
    if (folder === '_gemeinsam') return 'shared';
    if (folder?.startsWith('_benutzer/')) return 'private';
    return 'department';
}

async function handleScopeChange(e) {
    const id = e.target.dataset.id;
    const newScope = e.target.value;
    let templates = await getTemplates();
    const template = templates.find(t => t.id === id);
    if (!template) return;

    const oldScope = folderToScope(template.folder);
    if (oldScope === newScope) return;

    const authorEmail = await getAuthorEmail();
    if (newScope === 'private' && !authorEmail) {
        showToast('Bitte E-Mail in den Einstellungen eintragen.', 'error');
        e.target.value = oldScope;
        return;
    }

    // Warn on downgrade
    const scopeRank = { shared: 2, department: 1, private: 0 };
    if (scopeRank[newScope] < scopeRank[oldScope] && template.remotePath) {
        const confirmed = await showConfirmDialog(
            'Sichtbarkeit verringern?',
            'Die Vorlage wird am bisherigen Ort gelöscht. Andere Nutzer verlieren ggf. den Zugriff.',
            'Trotzdem ändern'
        );
        if (!confirmed) {
            e.target.value = oldScope;
            return;
        }
    }

    // Delete old remote file if exists
    if (template.remotePath) {
        try {
            await browser.runtime.sendMessage({
                action: 'deleteRemoteTemplate',
                remotePath: template.remotePath
            });
        } catch (_) {}
        template.remotePath = undefined;
    }

    // Set new folder
    if (newScope === 'shared') template.folder = '_gemeinsam';
    else if (newScope === 'private') template.folder = `_benutzer/${authorEmail}`;
    else template.folder = undefined;

    await saveTemplates(templates);

    // Auto-push to new location
    try {
        await browser.runtime.sendMessage({ action: 'pushTemplates' });
        templates = await getTemplates();
        storeTplHashes(templates);
    } catch (_) {}

    renderTemplates(templates);
    updateTplSyncIndicator();
    showToast('Sichtbarkeit geändert.', 'success');
}

// ── Bulk Actions ──

document.getElementById('select-all-button').addEventListener('click', () => {
    const checkboxes = document.querySelectorAll('.template-checkbox');
    const allChecked = Array.from(checkboxes).every(cb => cb.checked);
    checkboxes.forEach(cb => cb.checked = !allChecked);
});

document.getElementById('delete-selected-button').addEventListener('click', async () => {
    const checked = document.querySelectorAll('.template-checkbox:checked');
    if (checked.length === 0) return;
    const confirmed = await showConfirmDialog(
        'Ausgewählte löschen?',
        `${checked.length} Vorlage(n) wirklich löschen?`,
        `${checked.length} löschen`
    );
    if (!confirmed) return;

    const idsToDelete = new Set(Array.from(checked).map(cb => cb.dataset.id));
    let templates = await getTemplates();
    templates = templates.filter(t => !idsToDelete.has(t.id));
    await saveTemplates(templates);
    renderTemplates(templates);
    showToast(`${checked.length} Vorlage(n) gelöscht.`, 'info');
});

// ── HTML File Import ──

document.getElementById('import-button').addEventListener('click', async () => {
    const fileInput = document.getElementById('import-files');
    const statusEl = document.getElementById('import-status');
    const files = fileInput.files;

    if (files.length === 0) {
        showToast('Bitte Dateien auswählen!', 'error');
        return;
    }

    let templates = await getTemplates();
    let importCount = 0;

    for (const file of files) {
        const content = await file.text();
        const name = file.name.replace(/\.html?$/i, '');
        let body = content;
        const bodyMatch = content.match(/<body[^>]*>([\s\S]*)<\/body>/i);
        if (bodyMatch) body = bodyMatch[1].trim();

        const existingIndex = templates.findIndex(t => t.name.toLowerCase() === name.toLowerCase());
        if (existingIndex > -1) {
            templates[existingIndex].content = body;
        } else {
            templates.push({ id: Date.now().toString() + importCount, name, content: body });
        }
        importCount++;
    }

    await saveTemplates(templates);
    renderTemplates(templates);
    updateTplSyncIndicator();

    showToast(`${importCount} Vorlage(n) importiert!`, 'success');
    fileInput.value = '';
});

// ── Sync "Aktualisieren" Button (Pull + Push) ──

document.getElementById('sync-refresh-button').addEventListener('click', async () => {
    if (!checkOnline()) return;
    const btn = document.getElementById('sync-refresh-button');
    const origText = btn.textContent;
    btn.disabled = true;
    btn.innerHTML = '<span class="spinner spinner-dark"></span> Synchronisiere...';

    try {
        // Pull first
        const pullResult = await browser.runtime.sendMessage({ action: 'pullTemplates' });
        if (!pullResult?.success) {
            showToast(pullResult?.error || 'Fehler beim Laden', 'error', 6000);
            btn.disabled = false;
            btn.textContent = origText;
            return;
        }

        // Then push
        const pushResult = await browser.runtime.sendMessage({ action: 'pushTemplates' });

        const templates = await getTemplates();
        await checkForServerUpdates();
        storeTplHashes(templates);
        renderTemplates(templates);
        updateTplSyncIndicator();

        showToast(`${pullResult.updated || 0} geladen, ${pushResult?.pushed || 0} hochgeladen`, 'success');
    } catch (err) {
        showToast('Fehler: ' + err.message, 'error', 6000);
    }
    btn.disabled = false;
    btn.textContent = origText;
});

// ── Signaturen ──

async function getSigSourceMap() {
    const result = await browser.storage.local.get(SIG_SOURCE_KEY);
    return result[SIG_SOURCE_KEY] || {};
}

async function setSigSource(email, source) {
    const map = await getSigSourceMap();
    map[email.toLowerCase()] = source;
    await browser.storage.local.set({ [SIG_SOURCE_KEY]: map });
}

function updateSigSourceDropdown(currentEmail) {
    sigSourceSelect.innerHTML = '';

    const optOwn = document.createElement('option');
    optOwn.value = 'own';
    optOwn.textContent = 'Eigene Signatur';
    sigSourceSelect.appendChild(optOwn);

    for (const id of allIdentities) {
        if (id.email.toLowerCase() === currentEmail.toLowerCase()) continue;
        const opt = document.createElement('option');
        opt.value = '=' + id.email.toLowerCase();
        opt.textContent = `= ${id.email}`;
        sigSourceSelect.appendChild(opt);
    }
}

function updateSigEditorState(source) {
    const isEditable = (source === 'own');
    sigEditorArea.contentEditable = isEditable ? 'true' : 'false';
    sigEditorArea.style.opacity = isEditable ? '1' : '0.6';
    sigEditorArea.style.pointerEvents = isEditable ? 'auto' : 'none';
    document.querySelectorAll('#sig-toolbar button, #sig-toolbar select').forEach(el => {
        el.disabled = !isEditable;
        el.style.opacity = isEditable ? '1' : '0.4';
    });

    if (source === 'own') {
        sigSourceInfo.textContent = 'Eigene Signatur — wird im Editor bearbeitet.';
    } else if (source.startsWith('=')) {
        sigSourceInfo.textContent = `Übernimmt die Signatur von ${source.substring(1)}.`;
    }
}

async function loadIdentities() {
    allIdentities = [];
    sigIdentitySelect.innerHTML = '';

    const accounts = await browser.accounts.list();
    for (const account of accounts) {
        const identities = await browser.identities.list(account.id);
        for (const identity of identities) {
            const label = identity.name
                ? `${identity.name} <${identity.email}>`
                : identity.email;
            allIdentities.push({
                id: identity.id,
                email: identity.email,
                label,
                accountName: account.name,
                signature: identity.signature || '',
                signatureIsPlainText: identity.signatureIsPlainText || false
            });
            const opt = document.createElement('option');
            opt.value = identity.id;
            opt.textContent = `${label} (${account.name})`;
            sigIdentitySelect.appendChild(opt);
        }
    }

    // Auto-select first identity and load signature directly
    if (allIdentities.length > 0) {
        const first = allIdentities[0];
        sigIdentitySelect.value = first.id;

        const sourceMap = await getSigSourceMap();
        const source = sourceMap[first.email.toLowerCase()] || 'own';
        updateSigSourceDropdown(first.email);
        sigSourceSelect.value = source;

        if (source.startsWith('=')) {
            const srcEmail = source.substring(1);
            const srcIdentity = allIdentities.find(i => i.email.toLowerCase() === srcEmail);
            sigEditorArea.innerHTML = extractHeader(srcIdentity ? (srcIdentity.signature || '') : '');
        } else {
            sigEditorArea.innerHTML = extractHeader(first.signature || '');
        }
        updateSigEditorState(source);
    }
}

// Load signature header into editor when identity is selected
sigIdentitySelect.addEventListener('change', async () => {
    const identity = allIdentities.find(i => i.id === sigIdentitySelect.value);
    if (identity) {
        const sourceMap = await getSigSourceMap();
        const source = sourceMap[identity.email.toLowerCase()] || 'own';

        updateSigSourceDropdown(identity.email);
        sigSourceSelect.value = source;

        if (source.startsWith('=')) {
            const srcEmail = source.substring(1);
            const srcIdentity = allIdentities.find(i => i.email.toLowerCase() === srcEmail);
            sigEditorArea.innerHTML = extractHeader(srcIdentity ? (srcIdentity.signature || '') : '');
        } else {
            sigEditorArea.innerHTML = extractHeader(identity.signature || '');
        }
        updateSigEditorState(source);
    } else {
        sigEditorArea.innerHTML = '';
        sigSourceSelect.innerHTML = '<option value="own">Eigene Signatur</option>';
        sigSourceInfo.textContent = '';
    }
});

sigSourceSelect.addEventListener('change', async () => {
    const identity = allIdentities.find(i => i.id === sigIdentitySelect.value);
    if (!identity) return;

    const source = sigSourceSelect.value;
    await setSigSource(identity.email, source);
    updateSigEditorState(source);

    if (source.startsWith('=')) {
        const srcEmail = source.substring(1);
        const srcIdentity = allIdentities.find(i => i.email.toLowerCase() === srcEmail);
        sigEditorArea.innerHTML = extractHeader(srcIdentity ? (srcIdentity.signature || '') : '');
    } else {
        sigEditorArea.innerHTML = extractHeader(identity.signature || '');
    }
});

// ── Signature Header/Footer Helpers ──

// The footer separator comment in the combined signature
const FOOTER_SEPARATOR = '<!-- SIG_FOOTER_START -->';

function extractHeader(fullSignature) {
    const idx = fullSignature.indexOf(FOOTER_SEPARATOR);
    if (idx === -1) return fullSignature;
    return fullSignature.substring(0, idx).trim();
}

async function getFooter() {
    // Try to get fresh footer from server, fall back to cache
    try {
        const result = await browser.runtime.sendMessage({ action: 'loadFooter' });
        if (result && result.success && result.html) {
            return result.html;
        }
    } catch (_) {}
    // Fallback: cached version
    const cached = await browser.storage.local.get(SIG_FOOTER_KEY);
    return cached[SIG_FOOTER_KEY] || '';
}

function combineSignature(header, footer) {
    if (!footer) return header;
    return header + '\n' + FOOTER_SEPARATOR + '\n' + footer;
}

// Wendet den Footer lokal auf alle eingerichteten Identitäten an,
// indem der vorhandene Header (lokal) mit dem neuen Footer neu kombiniert wird.
// Funktioniert auch ohne hochgeladenen Server-Header.
async function applyFooterLocally(footer) {
    const sourceMap = await getSigSourceMap();
    let applied = 0;
    for (const identity of allIdentities) {
        const source = sourceMap[identity.email.toLowerCase()] || 'own';

        let header;
        if (source.startsWith('=')) {
            const srcEmail = source.substring(1);
            const srcIdentity = allIdentities.find(i => i.email.toLowerCase() === srcEmail);
            if (!srcIdentity) continue;
            header = extractHeader(srcIdentity.signature || '');
        } else {
            header = extractHeader(identity.signature || '');
        }

        // Unangetastete, leere Konten nicht mit einem reinen Footer versehen
        const alreadyManaged = (identity.signature || '').includes(FOOTER_SEPARATOR);
        if (!header.trim() && !alreadyManaged) continue;

        const fullSig = combineSignature(header, footer);
        if (fullSig === identity.signature) { applied++; continue; }

        await browser.identities.update(identity.id, {
            signature: fullSig,
            signatureIsPlainText: false,
        });
        identity.signature = fullSig;
        applied++;
    }
    return applied;
}

// ── "Vorlage laden" Button ──

document.getElementById('sig-load-template').addEventListener('click', async () => {
    const identity = allIdentities.find(i => i.id === sigIdentitySelect.value);
    if (!identity) {
        showSigStatus('Bitte zuerst eine Identität auswählen.', 'red');
        return;
    }

    showSigStatus('Lade Vorlage...', '#777');

    try {
        const result = await browser.runtime.sendMessage({ action: 'loadSignatureTemplate' });
        if (result && result.success) {
            let html = result.html;

            // Replace placeholders
            const authorName = document.getElementById('sync-author-name')?.value || '';
            const department = document.getElementById('sync-department')?.value || '';
            html = html.replace(/\{\{NAME\}\}/g, authorName || '{{NAME}}');
            html = html.replace(/\{\{EMAIL\}\}/g, identity.email);
            html = html.replace(/\{\{ABTEILUNG\}\}/g, department || '{{ABTEILUNG}}');
            html = html.replace(/\{\{TELEFON\}\}/g, '+49 (0) 5191 - 605-0');
            html = html.replace(/\{\{FAX\}\}/g, '+49 (0) 5191 - 605-185');

            sigEditorArea.innerHTML = html;

            // Set source to "own" since they're now editing
            await setSigSource(identity.email, 'own');
            sigSourceSelect.value = 'own';
            updateSigEditorState('own');

            showSigStatus('Vorlage geladen — bitte Abteilung und Telefon ausfüllen.', '#555');
        } else {
            showSigStatus(result?.error || 'Vorlage nicht gefunden', 'red');
        }
    } catch (err) {
        showSigStatus('Fehler: ' + err.message, 'red');
    }
});

function showSigStatus(message, color) {
    const type = color === 'green' ? 'success' : color === 'red' ? 'error' : 'info';
    showToast(message, type, type === 'error' ? 6000 : 4000);
}

// Save signature to Thunderbird identity (header + footer)
document.getElementById('sig-save-button').addEventListener('click', async () => {
  try {
    const identityId = sigIdentitySelect.value;
    if (!identityId) {
        showSigStatus('Bitte Identität auswählen.', 'red');
        return;
    }

    const identity = allIdentities.find(i => i.id === identityId);
    if (!identity) return;

    const sourceMap = await getSigSourceMap();
    const source = sourceMap[identity.email.toLowerCase()] || 'own';

    let header;
    if (source.startsWith('=')) {
        const srcEmail = source.substring(1);
        const srcIdentity = allIdentities.find(i => i.email.toLowerCase() === srcEmail);
        header = extractHeader(srcIdentity ? (srcIdentity.signature || '') : '');
    } else {
        header = sigEditorArea.innerHTML;
    }

    const footer = await getFooter();
    const fullSignature = combineSignature(header, footer);

    await browser.identities.update(identityId, {
        signature: fullSignature,
        signatureIsPlainText: false,
    });

    if (identity) identity.signature = fullSignature;

    // Update all identities that reference this email as source
    for (const otherId of allIdentities) {
        const otherSource = sourceMap[otherId.email.toLowerCase()] || 'own';
        if (otherSource === `=${identity.email.toLowerCase()}`) {
            await browser.identities.update(otherId.id, {
                signature: fullSignature,
                signatureIsPlainText: false,
                    });
            otherId.signature = fullSignature;
        }
    }

    updateSigSyncIndicator();

    // Auto-push to server, then pull to resolve reference chains
    try {
        await browser.runtime.sendMessage({ action: 'pushSignatures' });
    } catch (err) {
        showSigStatus('Gespeichert, aber Upload fehlgeschlagen: ' + err.message, '#e65100');
        return;
    }

    try {
        await browser.runtime.sendMessage({ action: 'pullSignatures' });
    } catch (_) {}

    await loadIdentities();
    for (const id of allIdentities) {
        sigSyncedHashes[id.email.toLowerCase()] = simpleHash(id.signature || '');
    }
    saveSyncHashes();
    updateSigSyncIndicator();
    const label = source.startsWith('=') ? ` (von ${source.substring(1)})` : '';
    showSigStatus(`Signatur gespeichert & hochgeladen!${label}`, 'green');
  } catch (err) {
    console.error('Signatur-Speichern Fehler:', err);
    showSigStatus('Fehler: ' + err.message, 'red');
  }
});

// Import signature from HTML file
document.getElementById('sig-import-file-btn').addEventListener('click', () => {
    document.getElementById('sig-import-file').click();
});

document.getElementById('sig-import-file').addEventListener('change', async (e) => {
    const files = Array.from(e.target.files);
    if (files.length === 0) return;

    const htmlFile = files.find(f => /\.html?$/i.test(f.name));
    const imageFiles = files.filter(f => f.type.startsWith('image/'));

    if (!htmlFile) {
        showSigStatus('Bitte eine HTML-Datei auswählen.', 'red');
        e.target.value = '';
        return;
    }

    const imageMap = {};
    for (const img of imageFiles) {
        const dataUri = await new Promise(resolve => {
            const reader = new FileReader();
            reader.onload = () => resolve(reader.result);
            reader.readAsDataURL(img);
        });
        imageMap[img.name.toLowerCase()] = dataUri;
    }

    let html = await htmlFile.text();
    const bodyMatch = html.match(/<body[^>]*>([\s\S]*)<\/body>/i);
    if (bodyMatch) html = bodyMatch[1].trim();

    html = html.replace(/<img\s+([^>]*?)src=["']([^"']+)["']/gi, (match, before, src) => {
        const filename = src.split('/').pop().split('\\').pop().toLowerCase();
        if (imageMap[filename]) return `<img ${before}src="${imageMap[filename]}"`;
        return match;
    });

    const unresolvedImages = (html.match(/<img[^>]+src=["'](?!data:)[^"']+["']/gi) || []).length;
    sigEditorArea.innerHTML = html;
    e.target.value = '';

    if (unresolvedImages > 0) {
        showSigStatus(`Geladen — ${unresolvedImages} Bild(er) nicht gefunden.`, '#e65100');
    } else {
        showSigStatus(`Geladen${imageFiles.length ? ` — ${imageFiles.length} Bild(er) eingebettet` : ''}. Jetzt speichern.`, '#555');
    }
});

// Signature sync - "Aktualisieren" (pull + push)
document.getElementById('sig-sync-refresh').addEventListener('click', async () => {
    if (!checkOnline()) return;
    const btn = document.getElementById('sig-sync-refresh');
    const origText = btn.textContent;
    btn.disabled = true;
    btn.innerHTML = '<span class="spinner spinner-dark"></span> Synchronisiere...';

    try {
        // Pull first (gets footer + headers)
        const pullResult = await browser.runtime.sendMessage({ action: 'pullSignatures' });
        if (!pullResult?.success) {
            showToast(pullResult?.error || 'Fehler', 'error', 6000);
            btn.disabled = false;
            btn.textContent = origText;
            return;
        }

        // Then push
        const pushResult = await browser.runtime.sendMessage({ action: 'pushSignatures' });

        await loadIdentities();
        for (const id of allIdentities) {
            sigSyncedHashes[id.email.toLowerCase()] = simpleHash(id.signature || '');
        }
        saveSyncHashes();
        updateSigSyncIndicator();
        sigIdentitySelect.dispatchEvent(new Event('change'));

        showToast(`${pullResult.updated || 0} geladen, ${pushResult?.pushed || 0} hochgeladen`, 'success');
    } catch (err) {
        showToast('Fehler: ' + err.message, 'error', 6000);
    }
    btn.disabled = false;
    btn.textContent = origText;
});

// ── Footer Editor ──

const footerEditorArea = document.getElementById('footer-editor-area');
const footerScopeSelect = document.getElementById('footer-scope');

setupToolbarCommands('footer-toolbar', footerEditorArea);
setupImageInsert('footer-insert-image', 'footer-image-file', footerEditorArea);

// Keep the "Abteilung" option label in sync with the selected department
function updateFooterScopeLabel() {
    const dept = document.getElementById('sync-department')?.value || '';
    const deptOption = footerScopeSelect?.querySelector('option[value="department"]');
    if (deptOption) {
        deptOption.textContent = dept ? `Abteilung: ${dept}` : 'Abteilung';
        deptOption.disabled = !dept;
    }
}

function currentFooterScope() {
    return footerScopeSelect?.value === 'department' ? 'department' : 'shared';
}

// Default-Auswahl: Abteilungs-Footer bevorzugen, wenn einer existiert.
// Sonst gemeinsam. Wird nur für die Vorbelegung genutzt — manuelles
// Umschalten bleibt erhalten.
async function pickDefaultFooterScope() {
    const dept = document.getElementById('sync-department')?.value || '';
    if (!dept) return 'shared';
    try {
        const res = await browser.runtime.sendMessage({ action: 'loadFooter', scope: 'department' });
        if (res && res.success && res.html) return 'department';
    } catch (_) {}
    return 'shared';
}

// Race-Schutz: nur das Ergebnis des zuletzt gestarteten Loads anwenden
let footerLoadSeq = 0;

// Load footer for the currently selected scope into the editor
async function loadFooterForScope(showStatus) {
    const scope = currentFooterScope();
    // Gleiche Offline-Prüfung wie bei den anderen Netzwerk-Aktionen
    if (showStatus && !checkOnline()) return;

    const seq = ++footerLoadSeq;
    const loadBtn = document.getElementById('footer-load-button');
    if (showStatus && loadBtn) loadBtn.disabled = true;
    if (showStatus) showFooterStatus('Lade...', '#777');
    try {
        const result = await browser.runtime.sendMessage({ action: 'loadFooter', scope });
        // Veralteter Lauf: ein neuerer Load wurde gestartet → Ergebnis verwerfen
        if (seq !== footerLoadSeq) return;
        if (result && result.success) {
            footerEditorArea.innerHTML = result.html || '';
            if (showStatus) {
                const where = scope === 'shared' ? 'gemeinsamer' : 'Abteilungs-';
                showFooterStatus(result.html ? `${where}Fußbereich geladen.` : `Noch kein ${where}Fußbereich vorhanden — du kannst einen anlegen.`, result.html ? 'green' : '#e65100');
            }
        } else if (showStatus) {
            showFooterStatus(result?.error || 'Fehler', 'red');
        }
    } catch (err) {
        if (seq === footerLoadSeq && showStatus) showFooterStatus('Fehler: ' + err.message, 'red');
    } finally {
        if (seq === footerLoadSeq && showStatus && loadBtn) loadBtn.disabled = false;
    }
}

document.getElementById('footer-toggle').addEventListener('click', async function() {
    this.classList.toggle('open');
    document.getElementById('footer-body').classList.toggle('open');

    // Auto-load footer when opening and editor is empty
    if (this.classList.contains('open') && (!footerEditorArea.innerHTML || footerEditorArea.innerHTML === '<br>')) {
        updateFooterScopeLabel();
        // Standardmäßig den Abteilungs-Footer vorbelegen, falls vorhanden
        if (footerScopeSelect) footerScopeSelect.value = await pickDefaultFooterScope();
        await loadFooterForScope(false);
    }
});

// Reload editor content when switching scope
footerScopeSelect?.addEventListener('change', () => loadFooterForScope(true));

function showFooterStatus(message, color) {
    const type = color === 'green' ? 'success' : color === 'red' ? 'error' : 'info';
    showToast(message, type, type === 'error' ? 6000 : 4000);
}

// Load footer from server
document.getElementById('footer-load-button').addEventListener('click', () => loadFooterForScope(true));

// Save & push footer
document.getElementById('footer-save-button').addEventListener('click', async () => {
    const html = footerEditorArea.innerHTML;
    if (!html || html === '<br>') {
        showFooterStatus('Fußbereich ist leer.', 'red');
        return;
    }

    if (!checkOnline()) return;
    const scope = currentFooterScope();
    const saveBtn = document.getElementById('footer-save-button');
    saveBtn.disabled = true;
    showFooterStatus('Speichere...', '#777');
    try {
        const result = await browser.runtime.sendMessage({ action: 'pushFooter', html, scope });
        if (!result || !result.success) {
            showFooterStatus(result?.error || 'Fehler', 'red');
            return;
        }

        // Neuen Footer direkt (lokal) auf die Thunderbird-Identitäten anwenden —
        // funktioniert auch ohne hochgeladenen Server-Header.
        const footer = await getFooter();
        const applied = await applyFooterLocally(footer);

        // Geänderte Header zusätzlich hochladen (best effort), damit andere
        // Geräte beim nächsten Sync den kombinierten Stand erhalten.
        try { await browser.runtime.sendMessage({ action: 'pushSignatures' }); } catch (_) {}

        for (const id of allIdentities) {
            sigSyncedHashes[id.email.toLowerCase()] = simpleHash(id.signature || '');
        }
        saveSyncHashes();
        updateSigSyncIndicator();
        // Aktuell geöffneten Signatur-Editor neu rendern
        sigIdentitySelect.dispatchEvent(new Event('change'));

        // Wenn "gemeinsam" gespeichert wurde, aber ein Abteilungs-Footer
        // existiert, verdeckt dieser den gemeinsamen beim Anwenden.
        let shadowed = false;
        if (scope === 'shared') {
            try {
                const dept = await browser.runtime.sendMessage({ action: 'loadFooter', scope: 'department' });
                shadowed = !!(dept && dept.success && dept.html);
            } catch (_) {}
        }

        const where = scope === 'shared' ? 'Gemeinsamer' : 'Abteilungs-';
        if (shadowed) {
            showFooterStatus('Gemeinsamer Fußbereich gespeichert — aber deine Abteilung hat einen eigenen Footer, der ihn überschreibt. Zum Anwenden den Abteilungs-Footer bearbeiten/löschen.', '#e65100');
        } else if (applied > 0) {
            showFooterStatus(`${where} Fußbereich gespeichert & in ${applied} Signatur(en) übernommen!`, 'green');
        } else {
            showFooterStatus(`${where} Fußbereich gespeichert. Hinweis: keine Signatur aktualisiert — erst eine persönliche Signatur speichern/hochladen.`, '#e65100');
        }
    } catch (err) {
        showFooterStatus('Fehler: ' + err.message, 'red');
    } finally {
        saveBtn.disabled = false;
    }
});

// ── Sync Settings UI ──

async function populateEmailDropdown() {
    const select = document.getElementById('sync-author-email');
    const accounts = await browser.accounts.list();
    const emails = new Set();
    for (const account of accounts) {
        for (const identity of account.identities) {
            if (identity.email && !emails.has(identity.email)) {
                emails.add(identity.email);
                const opt = document.createElement('option');
                opt.value = identity.email;
                opt.textContent = identity.email;
                select.appendChild(opt);
            }
        }
    }
}

async function populateFolderDropdown() {
    try {
        let options = '';
        const accounts = await browser.accounts.list();
        for (const account of accounts) {
            const folders = await browser.folders.getSubFolders(account);
            const addFolders = (list, prefix) => {
                for (const folder of list) {
                    const label = prefix ? `${prefix} / ${folder.name}` : `${account.name} / ${folder.name}`;
                    const val = JSON.stringify({ accountId: account.id, path: folder.path });
                    options += `<option value='${val.replace(/'/g, '&#39;')}'>${label}</option>`;
                    if (folder.subFolders && folder.subFolders.length) {
                        addFolders(folder.subFolders, label);
                    }
                }
            };
            addFolders(folders, '');
        }
        erledigtFolderOptions = options;
    } catch (e) {
        console.error('Ordner laden fehlgeschlagen:', e);
    }
}

async function loadSyncConfig() {
    try {
        const result = await browser.storage.local.get(SYNC_CONFIG_KEY);
        let config = result[SYNC_CONFIG_KEY];

        // First launch: load defaults from defaults.local.json if available
        if (!config) {
            try {
                const res = await fetch(browser.runtime.getURL('defaults.local.json'));
                if (res.ok) {
                    config = await res.json();
                    await browser.storage.local.set({ [SYNC_CONFIG_KEY]: config });
                }
            } catch (_) {}
        }

        if (config) {
            document.getElementById('sync-url').value = config.baseUrl || '';
            document.getElementById('sync-owner').value = config.owner || '';
            document.getElementById('sync-repo').value = config.repo || '';
            document.getElementById('sync-branch').value = config.branch || 'main';
            document.getElementById('sync-token').value = config.token || '';
            document.getElementById('sync-author-name').value = config.authorName || '';
            document.getElementById('sync-author-email').value = config.authorEmail || '';
            cachedAuthorEmail = config.authorEmail || '';
            if (config.baseUrl && config.token) {
                updateSyncStatus('connected', 'Verbunden');
            }
            if (config.department) {
                const deptSelect = document.getElementById('sync-department');
                const opt = document.createElement('option');
                opt.value = config.department;
                opt.textContent = config.department;
                opt.selected = true;
                deptSelect.appendChild(opt);
            }
            loadDepartments();

            // Auto-detect department + author from server config
            if (config.baseUrl && config.token) {
                tryAutoDetect(config);
            }
        }
    } catch (_) {}
}

async function tryAutoDetect(currentConfig) {
    try {
        const result = await browser.runtime.sendMessage({ action: 'autoDetect' });
        if (!result?.success || !result.config) return;

        // result.config = { "info@hotel.de": "Rezeption", ... }
        const deptMap = result.config;

        // Get all Thunderbird identities
        const accounts = await browser.accounts.list();
        const tbEmails = [];
        for (const account of accounts) {
            for (const identity of account.identities) {
                tbEmails.push(identity.email.toLowerCase());
            }
        }

        // Find matching department email
        let detectedDept = null;
        let personalEmail = null;
        const matchedEmails = [];
        const unmatchedEmails = [];

        for (const email of tbEmails) {
            if (deptMap[email]) {
                detectedDept = deptMap[email];
                matchedEmails.push(email);
            } else {
                unmatchedEmails.push(email);
            }
        }

        // The personal email is the one NOT in the department map
        if (unmatchedEmails.length > 0) {
            personalEmail = unmatchedEmails[0];
        }

        let changed = false;

        // Auto-set department if not already set
        if (detectedDept && !currentConfig.department) {
            const deptSelect = document.getElementById('sync-department');
            // Add option if not exists
            let found = false;
            for (const opt of deptSelect.options) {
                if (opt.value === detectedDept) { opt.selected = true; found = true; break; }
            }
            if (!found) {
                const opt = document.createElement('option');
                opt.value = detectedDept;
                opt.textContent = detectedDept;
                opt.selected = true;
                deptSelect.appendChild(opt);
            }
            currentConfig.department = detectedDept;
            changed = true;
        }

        // Auto-set author email if not already set
        if (personalEmail && !currentConfig.authorEmail) {
            document.getElementById('sync-author-email').value = personalEmail;
            currentConfig.authorEmail = personalEmail;
            cachedAuthorEmail = personalEmail;
            changed = true;
        }

        // Auto-set author name from TB identity if not already set
        if (personalEmail && !currentConfig.authorName) {
            for (const account of accounts) {
                for (const identity of account.identities) {
                    if (identity.email.toLowerCase() === personalEmail && identity.name) {
                        document.getElementById('sync-author-name').value = identity.name;
                        currentConfig.authorName = identity.name;
                        changed = true;
                        break;
                    }
                }
                if (changed && currentConfig.authorName) break;
            }
        }

        if (changed) {
            await browser.storage.local.set({ [SYNC_CONFIG_KEY]: currentConfig });
            showToast('Einstellungen automatisch erkannt.', 'info');
        }
    } catch (err) {
        console.log('Auto-detect failed (optional):', err.message);
    }
}

function getSyncConfigFromForm() {
    return {
        baseUrl: document.getElementById('sync-url').value.replace(/\/+$/, ''),
        owner: document.getElementById('sync-owner').value.trim(),
        repo: document.getElementById('sync-repo').value.trim(),
        branch: document.getElementById('sync-branch').value.trim() || 'main',
        token: document.getElementById('sync-token').value.trim(),
        authorName: document.getElementById('sync-author-name').value.trim(),
        authorEmail: document.getElementById('sync-author-email').value.trim(),
        department: document.getElementById('sync-department').value
    };
}

function updateSyncStatus(type, message) {
    const bar = document.getElementById('sync-status-bar');
    bar.className = 'sync-status ' + type;
    bar.textContent = message;
}

function showSyncActionStatus(elId, message, color) {
    const type = color === 'green' ? 'success' : color === 'red' ? 'error' : 'info';
    showToast(message, type, type === 'error' ? 6000 : 4000);
}

function appendSyncLog(message) {
    const log = document.getElementById('sync-log');
    log.style.display = 'block';
    const time = new Date().toLocaleTimeString('de-DE');
    log.textContent += `[${time}] ${message}\n`;
    log.scrollTop = log.scrollHeight;
}

async function loadDepartments() {
    try {
        const result = await browser.runtime.sendMessage({ action: 'listDepartments' });
        if (result && result.success) {
            const select = document.getElementById('sync-department');
            // Get saved department from config, not just DOM (more reliable)
            const configResult = await browser.storage.local.get(SYNC_CONFIG_KEY);
            const savedDept = configResult[SYNC_CONFIG_KEY]?.department || select.value || '';
            select.innerHTML = '<option value="">— Bitte wählen —</option>';
            for (const dept of result.departments) {
                const opt = document.createElement('option');
                opt.value = dept;
                opt.textContent = dept;
                if (dept === savedDept) opt.selected = true;
                select.appendChild(opt);
            }
            updateFooterScopeLabel();
        }
    } catch (_) {}
}

document.getElementById('save-sync-config').addEventListener('click', async () => {
    const config = getSyncConfigFromForm();
    if (!config.baseUrl || !config.owner || !config.repo || !config.token) {
        showSyncActionStatus('sync-action-status', 'Bitte alle Verbindungsfelder ausfüllen.', 'red');
        return;
    }

    try {
        const origin = new URL(config.baseUrl).origin + '/*';
        const granted = await browser.permissions.request({ origins: [origin] });
        if (!granted) {
            showSyncActionStatus('sync-action-status', 'Berechtigung für Server abgelehnt.', 'red');
            return;
        }
    } catch (err) {
        showSyncActionStatus('sync-action-status', 'Ungültige URL.', 'red');
        return;
    }

    await browser.storage.local.set({ [SYNC_CONFIG_KEY]: config });
    updateSyncStatus('connected', 'Verbunden');
    showSyncActionStatus('sync-action-status', 'Gespeichert!', 'green');
    appendSyncLog('Verbindung konfiguriert.');
    loadDepartments();
});

document.getElementById('sync-department').addEventListener('change', async () => {
    const result = await browser.storage.local.get(SYNC_CONFIG_KEY);
    const config = result[SYNC_CONFIG_KEY] || {};
    config.department = document.getElementById('sync-department').value;
    await browser.storage.local.set({ [SYNC_CONFIG_KEY]: config });

    updateFooterScopeLabel();

    if (config.department) {
        try {
            // Pull templates for new department
            const pullResult = await browser.runtime.sendMessage({ action: 'pullTemplates' });
            if (pullResult && pullResult.success) {
                const templates = await getTemplates();
                renderTemplates(templates);
                storeTplHashes(templates);
                updateTplSyncIndicator();
                appendSyncLog(`Abteilung gewechselt: ${config.department} — ${pullResult.updated || 0} Vorlage(n) geladen.`);
            }

            // Pull new department footer
            await browser.runtime.sendMessage({ action: 'pullSignatures' });
            // Clear footer editor so it reloads on next open
            if (footerEditorArea) footerEditorArea.innerHTML = '';
        } catch (_) {}
    }
});

for (const id of ['sync-author-name', 'sync-author-email']) {
    document.getElementById(id).addEventListener('change', async () => {
        const result = await browser.storage.local.get(SYNC_CONFIG_KEY);
        const config = result[SYNC_CONFIG_KEY] || {};
        config.authorName = document.getElementById('sync-author-name').value.trim();
        config.authorEmail = document.getElementById('sync-author-email').value.trim();
        await browser.storage.local.set({ [SYNC_CONFIG_KEY]: config });
    });
}

document.getElementById('refresh-departments').addEventListener('click', loadDepartments);

document.getElementById('add-department').addEventListener('click', async () => {
    const name = prompt('Name der neuen Abteilung:');
    if (!name || !name.trim()) return;
    try {
        const result = await browser.runtime.sendMessage({ action: 'addDepartment', name: name.trim() });
        if (result?.success) {
            showToast(`Abteilung "${name.trim()}" angelegt!`, 'success');
            await loadDepartments();
            document.getElementById('sync-department').value = name.trim();
        } else {
            showToast(result?.error || 'Fehler beim Anlegen', 'error');
        }
    } catch (e) {
        showToast('Fehler: ' + e.message, 'error');
    }
});

document.getElementById('test-sync-connection').addEventListener('click', async () => {
    if (!checkOnline()) return;
    const btn = document.getElementById('test-sync-connection');
    const origText = btn.textContent;
    btn.disabled = true;
    btn.innerHTML = '<span class="spinner spinner-dark"></span> Teste...';

    try {
        const result = await browser.runtime.sendMessage({ action: 'testConnection' });
        if (result && result.success) {
            updateSyncStatus('connected', 'Verbunden');
            showToast('Verbindung erfolgreich!', 'success');
            appendSyncLog('Verbindungstest erfolgreich.');
            loadDepartments();
        } else {
            updateSyncStatus('error', 'Verbindung fehlgeschlagen');
            showToast(result?.error || 'Fehler', 'error', 6000);
            appendSyncLog('Verbindungstest fehlgeschlagen: ' + (result?.error || 'Unbekannt'));
        }
    } catch (err) {
        updateSyncStatus('error', 'Verbindung fehlgeschlagen');
        showToast('Sync nicht verfügbar.', 'error', 6000);
    }
    btn.disabled = false;
    btn.textContent = origText;
});

// ── Erledigt-Tab ──

const ERLEDIGT_CONFIG_KEY = 'erledigt_config';
let erledigtFolderOptions = '';

function renderErledigtAction(action, index) {
    const div = document.createElement('div');
    div.className = 'form-row';
    div.style.alignItems = 'end';
    div.style.marginBottom = '8px';
    div.innerHTML = `
        <div class="form-group" style="flex:1;">
            ${index === 0 ? '<label>Name</label>' : ''}
            <input type="text" class="erledigt-name" placeholder="z.B. Erledigt" value="${(action.name || '').replace(/"/g, '&quot;')}">
        </div>
        <div class="form-group" style="flex:2;">
            ${index === 0 ? '<label>Zielordner</label>' : ''}
            <select class="erledigt-folder" style="width:100%;">
                <option value="">— Kein Ordner (nur markieren) —</option>
                ${erledigtFolderOptions}
            </select>
        </div>
        <div class="form-group" style="flex:0 0 auto;">
            ${index === 0 ? '<label>Gelesen</label>' : ''}
            <label style="display:flex;align-items:center;gap:6px;height:34px;white-space:nowrap;font-size:13px;cursor:pointer;">
                <input type="checkbox" class="erledigt-markread" ${action.markRead !== false ? 'checked' : ''}> als gelesen
            </label>
        </div>
        <button type="button" class="btn btn-danger btn-sm erledigt-remove" title="Entfernen" style="margin-bottom:2px;">✕</button>
    `;
    if (action.targetFolder) {
        div.querySelector('.erledigt-folder').value = action.targetFolder;
    }
    div.querySelector('.erledigt-remove').addEventListener('click', () => {
        div.remove();
    });
    return div;
}

function renderErledigtActions(actions) {
    const list = document.getElementById('erledigt-actions-list');
    list.innerHTML = '';
    actions.forEach((a, i) => list.appendChild(renderErledigtAction(a, i)));
}

function getErledigtActionsFromForm() {
    const actions = [];
    const names = document.querySelectorAll('.erledigt-name');
    const folders = document.querySelectorAll('.erledigt-folder');
    const reads = document.querySelectorAll('.erledigt-markread');
    for (let i = 0; i < names.length; i++) {
        const name = names[i].value.trim();
        if (!name) continue;
        actions.push({ name, targetFolder: folders[i].value || '', markRead: reads[i] ? reads[i].checked : true });
    }
    return actions;
}

async function loadErledigtConfig() {
    const result = await browser.storage.local.get(ERLEDIGT_CONFIG_KEY);
    const config = result[ERLEDIGT_CONFIG_KEY] || {};
    const actions = config.actions || [];
    if (actions.length === 0) actions.push({ name: 'Erledigt', targetFolder: '' });
    renderErledigtActions(actions);
}

document.getElementById('add-erledigt-action').addEventListener('click', () => {
    const list = document.getElementById('erledigt-actions-list');
    list.appendChild(renderErledigtAction({ name: '', targetFolder: '' }, list.children.length));
});

document.getElementById('save-erledigt-config').addEventListener('click', async () => {
    const actions = getErledigtActionsFromForm();
    if (actions.length === 0) {
        showToast('Mindestens eine Aktion mit Namen anlegen.', 'error');
        return;
    }
    await browser.storage.local.set({ [ERLEDIGT_CONFIG_KEY]: { actions } });
    showToast('Aktionen gespeichert!', 'success');
});

// ── Init ──

window.addEventListener('load', async () => {
    await loadSyncHashes();
    const templates = await getTemplates();
    renderTemplates(templates);
    updateTplSyncIndicator();
    await populateEmailDropdown();
    await populateFolderDropdown();
    await loadErledigtConfig();
    loadSyncConfig();
    await loadIdentities();

    // Always init sig hashes from current identities
    if (allIdentities.length > 0) {
        for (const id of allIdentities) {
            sigSyncedHashes[id.email.toLowerCase()] = simpleHash(id.signature || '');
        }
        saveSyncHashes();
    }
    updateSigSyncIndicator();

    checkForServerUpdates();
    setInterval(checkForServerUpdates, 30000);

    // Auto-refresh UI when background sync updates storage
    let refreshing = false;
    browser.storage.onChanged.addListener(async (changes, area) => {
        if (area !== 'local' || refreshing) return;
        if (changes[HASH_STORAGE_KEY] || changes[TEMPLATE_STORAGE_KEY]) {
            refreshing = true;
            await loadSyncHashes();
            const templates = await getTemplates();
            renderTemplates(templates);
            updateTplSyncIndicator();
            updateSigSyncIndicator();
            refreshing = false;
        }
    });
});

// ── Opt-out-Schalter für erzwungene Prefs ──
// FORCED_PREFS / FORCED_IDENTITY_PREFS stammen aus ../lib/forced-prefs-list.js
// (im HTML vor diesem Script geladen). Gespeichert werden die ids der
// DEAKTIVIERTEN Prefs unter 'forced_prefs_optout'; Haken = wird erzwungen.
const FORCED_PREFS_OPTOUT_KEY = 'forced_prefs_optout';

async function renderForcedPrefsToggles() {
    const container = document.getElementById('forced-prefs-list');
    if (!container || typeof FORCED_PREFS === 'undefined') return;

    const stored = await browser.storage.local.get(FORCED_PREFS_OPTOUT_KEY);
    const disabled = new Set(stored[FORCED_PREFS_OPTOUT_KEY] || []);

    container.textContent = '';
    const entries = [...FORCED_PREFS, ...(typeof FORCED_IDENTITY_PREFS !== 'undefined' ? FORCED_IDENTITY_PREFS : [])];
    for (const p of entries) {
        const row = document.createElement('label');
        row.className = 'forced-pref-row';
        row.style.display = 'flex';
        row.style.alignItems = 'center';
        row.style.gap = '8px';
        row.style.padding = '4px 0';
        row.style.cursor = 'pointer';

        const cb = document.createElement('input');
        cb.type = 'checkbox';
        cb.checked = !disabled.has(p.id); // Haken = wird erzwungen
        cb.addEventListener('change', () => setForcedPrefEnabled(p.id, cb.checked));

        const span = document.createElement('span');
        span.textContent = p.label;

        row.append(cb, span);
        container.appendChild(row);
    }
}

async function setForcedPrefEnabled(id, enabled) {
    const stored = await browser.storage.local.get(FORCED_PREFS_OPTOUT_KEY);
    const disabled = new Set(stored[FORCED_PREFS_OPTOUT_KEY] || []);
    if (enabled) disabled.delete(id);
    else disabled.add(id);
    await browser.storage.local.set({ [FORCED_PREFS_OPTOUT_KEY]: [...disabled] });
    // background.js lauscht auf storage.onChanged und wendet Aktivierungen sofort an.
}

document.addEventListener('DOMContentLoaded', renderForcedPrefsToggles);
