/**
 * Fichier  : assets/js/pages/settings.js
 * Auteur   : KREMER Régis
 * Version  : 2.5.0
 * Date     : 2026-03-01
 * Description : JS — Paramètres : config, backup, push, archivage annuel, danger
 *
 * Changelog :
 *   v2.2.1 — Fix IDs, handlers backup/restore
 *   v2.5.0 — Module archivage, reminder annuel, push device info, layout settings
 */

// ================================================================
// settings.js — Paramètres
// ================================================================
const SetPage = {

    async init() {
        const root = document.getElementById('pgSettings');
        if (!root) return;

        this.initLangGrid();

        const $ = (id) => document.getElementById(id);

        const inpCompany = $('settCompanyName');
        const inpSku     = $('settSkuPrefix');
        const btnSave    = $('btnSaveSettings');
        const btnBackup  = $('btnBackup');
        const btnRestore = $('btnRestore');
        const fileInput  = $('restoreFileInput');
        const btnDelProd = $('btnDeleteProducts');
        const btnDelMov  = $('btnDeleteMovements');
        const btnDelAll  = $('btnDeleteAll');

        // Charger settings
        try {
            const s = await Api.settings();
            if (inpCompany) inpCompany.value = s.companyName || '';
            if (inpSku)     inpSku.value     = s.skuPrefix   || 'PRD-';
        } catch (e) {
            toast(e.message || 'Impossible de charger les paramètres', 'error');
        }

        // Save
        if (btnSave) btnSave.onclick = () => this.saveSettings(inpCompany, inpSku);

        // Backup export
        if (btnBackup) {
            btnBackup.onclick = () => {
                try { Api.backupExport(); }
                catch (e) { toast(e.message || 'Export impossible', 'error'); }
            };
        }

        // Backup import
        if (btnRestore && fileInput) {
            btnRestore.onclick = () => fileInput.click();
            fileInput.onchange = async () => {
                const f = fileInput.files && fileInput.files[0];
                if (!f) return;
                if (!confirm("Importer cette sauvegarde ?\n\nCette action remplace vos données actuelles.\nAssurez-vous d'avoir exporté avant.")) {
                    fileInput.value = '';
                    return;
                }
                try {
                    const json = JSON.parse(await f.text());
                    await Api.backupImport(json);
                    toast('Sauvegarde importée', 'success');
                    setTimeout(() => location.reload(), 800);
                } catch (e) {
                    toast(e.message || 'Import impossible (JSON invalide ?)', 'error');
                } finally {
                    fileInput.value = '';
                }
            };
        }

        // Danger zone
        if (btnDelProd) btnDelProd.onclick = () => this.clearEntity('products', 'tous les produits et leur stock');
        if (btnDelMov)  btnDelMov.onclick  = () => this.clearEntity('movements', 'tous les mouvements');
        if (btnDelAll)  btnDelAll.onclick  = () => this.clearAll();

        // Push — initialiser l'UI
        this.initPushUI();

        // Archivage
        await this.loadArchive();
    },

    // ══════════════════════════════════════════════════════════════
    // SETTINGS SAVE
    // ══════════════════════════════════════════════════════════════
    async saveSettings(inpCompany, inpSku) {
        try {
            const companyName = (inpCompany ? inpCompany.value : '').trim();
            const skuPrefix   = (inpSku ? inpSku.value : '').trim() || 'PRD-';
            await Api.settingsSave({ companyName, skuPrefix });
            toast('Paramètres sauvegardés', 'success');
            location.reload();
        } catch (e) {
            toast(e.message || 'Erreur sauvegarde paramètres', 'error');
        }
    },

    // ══════════════════════════════════════════════════════════════
    // PUSH NOTIFICATIONS — UI enrichie
    // ══════════════════════════════════════════════════════════════
    initPushUI() {
        const unsupEl = document.getElementById('pushUnsupported');
        const suppEl  = document.getElementById('pushSupported');

        const pushSupported = ('serviceWorker' in navigator) && ('PushManager' in window) && ('Notification' in window);
        if (!pushSupported) {
            if (unsupEl) unsupEl.style.display = 'flex';
            if (suppEl)  suppEl.style.display  = 'none';
            return;
        }

        if (unsupEl) unsupEl.style.display = 'none';
        if (suppEl)  suppEl.style.display  = 'block';

        // Afficher info appareil si déjà abonné
        this._refreshPushDeviceInfo();
    },

    _refreshPushDeviceInfo() {
        const infoEl = document.getElementById('pushDeviceInfo');
        if (!infoEl) return;

        const isSubscribed = (window.SMPush && window.SMPush.isSubscribed);
        if (!isSubscribed) { infoEl.style.display = 'none'; return; }

        const ua   = navigator.userAgent;
        let browser = 'Navigateur inconnu';
        if (ua.includes('Edg/'))    browser = 'Microsoft Edge';
        else if (ua.includes('Chrome/'))  browser = 'Google Chrome';
        else if (ua.includes('Firefox/')) browser = 'Mozilla Firefox';
        else if (ua.includes('Safari/'))  browser = 'Safari';

        const os = ua.includes('Windows') ? 'Windows'
                 : ua.includes('Mac')     ? 'macOS'
                 : ua.includes('Linux')   ? 'Linux'
                 : ua.includes('Android') ? 'Android'
                 : ua.includes('iPhone') || ua.includes('iPad') ? 'iOS'
                 : 'OS inconnu';

        infoEl.style.display = 'flex';
        infoEl.innerHTML = `
            <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" style="flex-shrink:0;margin-top:1px">
                <rect x="5" y="2" width="14" height="20" rx="2" ry="2"/>
                <line x1="12" y1="18" x2="12.01" y2="18"/>
            </svg>
            <span>Cet appareil est abonné — <strong>${browser}</strong> sur <strong>${os}</strong></span>
        `;
    },

    // ══════════════════════════════════════════════════════════════
    // ARCHIVAGE
    // ══════════════════════════════════════════════════════════════
    async loadArchive() {
        try {
            // Statut (rappel annuel)
            const status = await Api.archiveStatus();

            if (status.needsReminder) {
                const reminder = document.getElementById('archiveReminder');
                if (reminder) reminder.style.display = 'flex';
            }

            const infoEl = document.getElementById('lastArchiveInfo');
            if (infoEl) {
                infoEl.textContent = status.lastArchiveAt
                    ? 'Dernier archivage : ' + this._fmtDate(status.lastArchiveAt)
                    : 'Aucun archivage effectué';
            }

            // Checkboxes entités avec comptages live
            await this._renderEntityChecks();

            // Liste des archives
            await this._renderArchiveList();

        } catch (e) {
            console.error('[Archive] Erreur chargement:', e);
        }
    },

    async _renderEntityChecks() {
        const container = document.getElementById('archiveEntityChecks');
        if (!container) return;

        const ENTITIES = [
            { key: 'products',         label: 'Produits',         icon: '📦' },
            { key: 'stock',            label: 'Stock',            icon: '🏪' },
            { key: 'movements',        label: 'Mouvements',       icon: '🔄' },
            { key: 'inventories',      label: 'Inventaires',      icon: '📋' },
            { key: 'orders',           label: 'Commandes',        icon: '🛒' },
            { key: 'alerts',           label: 'Alertes',          icon: '⚠️' },
            { key: 'product_versions', label: 'Versions produits', icon: '📝' },
        ];

        // Charger les comptages via backup (approximatif — on utilise les API existantes)
        const counts = {};
        try {
            const [prods, movs] = await Promise.all([Api.products(), Api.movements?.() || []]);
            counts.products  = prods.length;
            counts.movements = movs.length;
        } catch(e) {}

        container.innerHTML = ENTITIES.map(e => `
            <label class="archive-entity-check">
                <input type="checkbox" class="archive-entity-cb" value="${e.key}" checked>
                <span class="archive-entity-icon">${e.icon}</span>
                <span class="archive-entity-label">${e.label}</span>
                ${counts[e.key] !== undefined ? `<span class="archive-entity-count">${counts[e.key]}</span>` : ''}
            </label>
        `).join('');
    },

    async _renderArchiveList() {
        const container = document.getElementById('archiveList');
        if (!container) return;

        try {
            const archives = await Api.archiveList();

            if (!archives.length) {
                container.innerHTML = `<div class="archive-empty">
                    <svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="currentColor" stroke-width="1.5">
                        <path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><line x1="10" y1="12" x2="14" y2="12"/>
                    </svg>
                    <p>Aucune archive — créez votre première archive ci-dessus.</p>
                </div>`;
                return;
            }

            container.innerHTML = `
                <div class="archive-table-wrap">
                    <table class="data-table">
                        <thead>
                            <tr>
                                <th>Libellé</th>
                                <th>Année</th>
                                <th>Date de création</th>
                                <th>Contenu</th>
                                <th class="cell-number">Taille</th>
                                <th class="cell-actions">Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            ${archives.map(a => `
                                <tr>
                                    <td><strong>${this._esc(a.label)}</strong></td>
                                    <td>${a.year || '—'}</td>
                                    <td>${this._fmtDate(a.createdAt)}</td>
                                    <td>
                                        <div class="archive-pills">
                                            ${(a.entities||[]).map(e => `
                                                <span class="archive-pill">${e}${a.counts?.[e] ? ' <em>('+a.counts[e]+')</em>' : ''}</span>
                                            `).join('')}
                                        </div>
                                    </td>
                                    <td class="cell-number">${a.sizeHuman}</td>
                                    <td style="display:flex;gap:4px">
                                        <button class="btn btn-sm btn-secondary" title="Lire l'archive" onclick="SetPage.readArchive('${this._esc(a.file)}')">
                                            <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
                                        </button>
                                        <button class="btn btn-sm btn-warning" title="Restaurer" onclick="SetPage.restoreArchive('${this._esc(a.file)}', '${this._esc(a.label)}')">
                                            <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 102.13-9.36L1 10"/></svg>
                                        </button>
                                        <button class="btn btn-sm btn-danger" title="Supprimer" onclick="SetPage.deleteArchive('${this._esc(a.file)}', '${this._esc(a.label)}')">
                                            ${Icons.trash}
                                        </button>
                                    </td>
                                </tr>
                            `).join('')}
                        </tbody>
                    </table>
                </div>`;
        } catch (e) {
            container.innerHTML = `<div style="color:var(--red);padding:12px">Erreur chargement des archives</div>`;
        }
    },

    async createArchive() {
        const label    = document.getElementById('archiveLabel')?.value?.trim() || '';
        const year     = document.getElementById('archiveYear')?.value || String(new Date().getFullYear() - 1);
        const checked  = [...document.querySelectorAll('.archive-entity-cb:checked')].map(cb => cb.value);

        if (!checked.length) { toast('Sélectionnez au moins une entité à archiver', 'warning'); return; }

        const fullLabel = label || `Archive ${year}`;

        if (!confirm(`Créer l'archive "${fullLabel}" ?\n\nEntités : ${checked.join(', ')}\n\nCette opération peut prendre quelques secondes.`)) return;

        const btn = document.getElementById('btnCreateArchive');
        if (btn) { btn.disabled = true; btn.textContent = 'Archivage…'; }

        try {
            const res = await Api.archiveCreate({ label: fullLabel, year, entities: checked });
            toast(`Archive créée — ${res.sizeHuman} (${Object.values(res.counts||{}).reduce((a,b)=>a+b,0)} enregistrements)`, 'success');
            document.getElementById('archiveLabel').value = '';
            await this._renderArchiveList();
            // Mettre à jour l'info dernier archivage
            const infoEl = document.getElementById('lastArchiveInfo');
            if (infoEl) infoEl.textContent = 'Dernier archivage : ' + this._fmtDate(new Date().toISOString());
            // Masquer le rappel
            const reminder = document.getElementById('archiveReminder');
            if (reminder) reminder.style.display = 'none';
        } catch (e) {
            toast(e.message || 'Erreur création archive', 'error');
        } finally {
            if (btn) { btn.disabled = false; btn.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/></svg> Créer l\'archive'; }
        }
    },

    async readArchive(file) {
        try {
            const archive = await Api.archiveRead(file);

            const entities = Object.keys(archive.data || {});
            let html = `
                <div style="margin-bottom:16px">
                    <strong>${this._esc(archive.label || file)}</strong>
                    <span class="text-muted" style="margin-left:8px;font-size:12px">
                        Créé le ${this._fmtDate(archive.createdAt)} par ${this._esc(archive.createdBy || '?')}
                    </span>
                </div>
                <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px">
                    ${entities.map(e => {
                        const items = archive.data[e] || [];
                        return `<div class="archive-read-card">
                            <div class="archive-read-entity">${this._esc(e)}</div>
                            <div class="archive-read-count">${items.length} enregistrements</div>
                        </div>`;
                    }).join('')}
                </div>`;

            Modal.show('Contenu de l\'archive', html, [
                { label: 'Fermer', cls: 'btn-secondary', onclick: () => Modal.close() },
                { label: 'Restaurer', cls: 'btn-warning', onclick: () => { Modal.close(); this.restoreArchive(file, archive.label); } },
            ], 'info');

        } catch (e) {
            toast(e.message || 'Erreur lecture archive', 'error');
        }
    },

    async restoreArchive(file, label) {
        if (!confirm(`Restaurer l'archive "${label}" ?\n\nATTENTION : Les données actuelles seront remplacées par celles de l'archive pour les entités archivées.\n\nCette action est irréversible.`)) return;
        try {
            const res = await Api.archiveRestore(file);
            const total = Object.values(res.restored || {}).reduce((a,b) => a+b, 0);
            toast(`Archive restaurée — ${total} enregistrements remis en place`, 'success');
            setTimeout(() => location.reload(), 1200);
        } catch (e) {
            toast(e.message || 'Erreur restauration', 'error');
        }
    },

    async deleteArchive(file, label) {
        if (!confirm(`Supprimer définitivement l'archive "${label}" ?`)) return;
        try {
            await Api.archiveDelete(file);
            toast('Archive supprimée', 'success');
            await this._renderArchiveList();
        } catch (e) {
            toast(e.message || 'Erreur suppression archive', 'error');
        }
    },

    scrollToArchive() {
        const el = document.getElementById('archiveSection');
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    },

    // ══════════════════════════════════════════════════════════════
    // DANGER ZONE
    // ══════════════════════════════════════════════════════════════
    async clearEntity(entity, label) {
        if (!confirm('Supprimer ' + label + ' ? IRRÉVERSIBLE !')) return;
        try {
            if (entity === 'products') {
                const prods = await Api.products();
                for (const p of prods) await Api.prodDel(p.id);
            } else if (entity === 'movements') {
                await Api.mvClear();
            }
            toast(label.charAt(0).toUpperCase() + label.slice(1) + ' supprimé(s)', 'success');
            location.reload();
        } catch (e) {
            toast(e.message || 'Erreur suppression', 'error');
        }
    },

    async clearAll() {
        if (!confirm(
            "SUPPRIMER TOUTES LES DONNÉES ?\n\n" +
            "Produits, stock, mouvements, magasins, alertes, inventaires.\n\n" +
            "Cette action est IRRÉVERSIBLE.\n\nSauvegardez d'abord !"
        )) return;
        try {
            const prods = await Api.products();
            for (const p of prods) await Api.prodDel(p.id);
            await Api.mvClear();
            const whs = await Api.warehouses();
            for (const w of whs) await Api.whDel(w.id);
            toast('Toutes les données ont été supprimées', 'success');
            setTimeout(() => location.reload(), 1200);
        } catch (e) {
            toast(e.message || 'Erreur suppression totale', 'error');
        }
    },

    // ══════════════════════════════════════════════════════════════
    // LANGUE
    // ══════════════════════════════════════════════════════════════
    initLangGrid() {
        const grid = document.getElementById('langGrid');
        if (!grid) return;
        const I18N      = window.I18N      || {};
        const FLAGS     = I18N.FLAGS       || {};
        const NAMES     = I18N.NAMES       || {};
        const SUPPORTED = I18N.SUPPORTED   || ['fr', 'en'];
        const render = () => {
            const cur = window.SM_LANG || 'fr';
            grid.innerHTML = SUPPORTED.map(lang => `
                <button class="lang-card${lang === cur ? ' active' : ''}" data-lang="${lang}">
                    <span class="lang-card-flag">${FLAGS[lang] || '🌐'}</span>
                    <span class="lang-card-name">${NAMES[lang] || lang}</span>
                    <span class="lang-card-check">✓</span>
                </button>
            `).join('');
            grid.querySelectorAll('[data-lang]').forEach(btn => {
                btn.addEventListener('click', async () => {
                    const lang = btn.dataset.lang;
                    if (lang === window.SM_LANG) return;
                    grid.querySelectorAll('.lang-card').forEach(b => b.classList.remove('active'));
                    btn.classList.add('active');
                    try {
                        await window.setLang(lang);
                        toast('Langue : ' + (NAMES[lang] || lang), 'success');
                        render();
                    } catch (e) {
                        toast('Erreur changement de langue', 'error');
                        render();
                    }
                });
            });
        };
        render();
    },

    // ══════════════════════════════════════════════════════════════
    // HELPERS
    // ══════════════════════════════════════════════════════════════
    _esc(s) {
        return String(s || '').replace(/[&<>"']/g, m =>
            ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' }[m]));
    },

    _fmtDate(iso) {
        if (!iso) return '—';
        try {
            const d = new Date(iso);
            return d.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
        } catch { return iso; }
    },
};
