// Exporteur HTML autonome de l'onglet Budget Cybersecurite (styles + graphiques integres).
// (audit 2026-07-10) l'ancienne section de scoring CyFun a ete retiree (generique multi-referentiels).

(() => {
  const MODULE_ID = 'nis2-program';
  const STYLE_FILE = 'style.css';

  function tt(key, fallback) {
    return typeof window.t === 'function' ? window.t(key) : (fallback || key);
  }

  // (audit 2026-07-10) section de synthèse CyFun supprimée : débranchée depuis le passage
  // au Budget Cybersécurité générique — code mort retiré.

  /**
   * Exporte la page NIS2 en HTML autonome avec tous les styles
   */
  async function exportNis2Html() {
    // Bloquer l'export en mode demo
    var isDemo = (function() {
      var meta = document.querySelector('meta[name="csi-mode"]');
      return meta && meta.content === 'demo';
    })();
    if (isDemo) {
      var toastFn = window.showToast || window.showToast2 || showToast;
      if (toastFn) {
        toastFn(tt('exportLabels.htmlExportDisabled', 'L\'export HTML est desactive en mode demonstration.'), 'warning');
      } else {
        alert(tt('exportLabels.htmlExportDisabled', 'L\'export HTML est desactive en mode demonstration.'));
      }
      return;
    }
    try {
      showToast(tt('exportLabels.preparingExport', 'Preparation de l\'export...'), 'info');

      // Obtenir le module NIS2
      var nis2Module = document.getElementById(MODULE_ID);
      if (!nis2Module) {
        throw new Error(tt('exportLabels.nis2ModuleNotFound', 'Module NIS2 non trouve'));
      }

      // Charger le CSS
      var cssContent = await loadCssContent();

      // Cloner le module
      var clone = nis2Module.cloneNode(true);
      prepareElementForExport(clone);

      // Convertir les canvas en images
      await convertCanvasesToImages(clone);

      // Export Budget Cybersécurité : pas d'annexe de scoring CyFun (l'onglet n'est plus
      // spécifique NIS2 ; l'ancienne section était figée CyFun et erronée en mode ReCyF/France).

      // Creer le HTML complet
      var htmlContent = generateStandaloneHtml(clone, cssContent);

      // Telecharger le fichier
      downloadHtml(htmlContent, 'budget-cybersecurite-' + new Date().toISOString().split('T')[0] + '.html');

      showToast(tt('exportLabels.htmlExportSuccess', 'Export HTML reussi!'), 'success');

    } catch (error) {
      void 0;
      showToast(tt('common.error', 'Erreur') + ': ' + error.message, 'error');
    }
  }

  /**
   * Charge le contenu du CSS
   */
  async function loadCssContent() {
    try {
      var response = await fetch(STYLE_FILE);
      if (!response.ok) throw new Error('Impossible de charger le CSS');
      return await response.text();
    } catch (error) {
      void 0;
      // FIX-NIS2-EXPORT-CSS-FILE (audit 2026-06-10) : en file:// (Chromium), fetch('style.css')
      // échoue TOUJOURS (« Failed to fetch ») et l'accès à cssRules des feuilles <link> lève
      // SecurityError (chaque ressource file:// est une origine opaque) → le fichier exporté
      // partait quasiment sans styles. Quand l'extraction récupère trop peu de CSS (seuls les
      // petits <style> injectés dynamiquement restent lisibles, ~300 caractères, contre des
      // dizaines de Ko pour style.css), on embarque le bloc de repli autonome getFallbackCss().
      var extracted = extractInlineCss();
      if (extracted && extracted.length > 2000) return extracted;
      return (extracted || '') + '\n' + getFallbackCss();
    }
  }

  // FIX-NIS2-EXPORT-CSS-FILE (audit 2026-06-10) : styles minimaux autonomes garantissant un
  // rendu correct de l'export NIS2 (titres, grilles de cartes, tableaux, listes de statuts,
  // barres de progression) quand le CSS de l'application est inaccessible (mode file://).
  function getFallbackCss() {
    return [
      'h1,h2,h3,h4{color:#1f2937;margin:18px 0 10px}',
      'h2{font-size:24px;border-bottom:2px solid #1fb8cd;padding-bottom:6px}',
      'h3{font-size:18px}',
      'h4{font-size:15px}',
      'p{margin:6px 0;line-height:1.5}',
      'img{max-width:100%;height:auto}',
      'table{width:100%;border-collapse:collapse;margin:12px 0;font-size:13px}',
      'th{background:#1fb8cd;color:#fff;text-align:left;padding:8px 10px;border:1px solid #d7dde3}',
      'td{padding:6px 10px;border:1px solid #e2e8f0;vertical-align:top}',
      'tbody tr:nth-child(even){background:#f8fafc}',
      'ul,ol{margin:8px 0;padding-left:22px}',
      '.module__title{font-size:26px;color:#1fb8cd;margin:0 0 16px 0}',
      '.charts-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px;margin:16px 0}',
      '.chart-card{border:1px solid #e2e8f0;border-radius:8px;padding:16px;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.06)}',
      '.chart-card__header{margin-bottom:10px}',
      '.chart-card__title{margin:0;font-size:16px;color:#334155}',
      '.chart-card__subtitle{margin:2px 0 0;font-size:12px;color:#64748b}',
      '.chart-legend,.actions-legend{font-size:12px;color:#475569;margin-top:8px}',
      '.info-box{display:flex;gap:10px;background:#eef9fb;border-left:4px solid #1fb8cd;padding:12px 14px;border-radius:6px;margin:12px 0}',
      '.info-box__icon{color:#1fb8cd}',
      '.info-box__text{font-size:13px;color:#334155}',
      '.nis2-status-list{list-style:none;margin:8px 0;padding:0}',
      '.nis2-status-list li{padding:6px 0;border-bottom:1px solid #eef2f6;font-size:13px}',
      '.nis2-status-dot{display:inline-block;width:10px;height:10px;border-radius:50%;background:#9ca3af;margin-right:8px}',
      '.nis2-status-dot--todo{background:#9ca3af}',
      '.nis2-status-dot--progress{background:#d97706}',
      '.nis2-status-dot--done{background:#059669}',
      '.chip{display:inline-block;padding:2px 8px;border-radius:10px;background:#eef2f6;color:#334155;font-size:11px;margin:0 4px 2px 0}',
      '.progress-bar{position:relative;height:8px;background:#e2e8f0;border-radius:4px;overflow:hidden;min-width:60px}',
      '.progress-bar__fill{position:absolute;left:0;top:0;bottom:0;background:#1fb8cd}',
      '.progress-label{font-size:11px;color:#475569}',
      '.nis2-phase-group{margin:14px 0}',
      '.nis2-action-main{font-size:13px}',
      '.nis2-action-meta{font-size:11px;color:#64748b}',
      '.nis2-plan-summary-strip{display:flex;flex-wrap:wrap;gap:12px;padding:10px 0;font-size:13px}',
      '.socle-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;margin:14px 0}',
      '.text-center{text-align:center}',
      '.text-right{text-align:right}',
      'button,.icon-btn,.module__actions,.sr-only{display:none!important}'
    ].join('\n');
  }

  /**
   * Extrait les styles CSS deja charges dans le document
   */
  function extractInlineCss() {
    var styles = [];
    document.querySelectorAll('style').forEach(function(el) { styles.push(el.textContent || ''); });
    Array.from(document.styleSheets || []).forEach(function(sheet) {
      try {
        var rules = sheet.cssRules || [];
        styles.push(Array.from(rules).map(function(r) { return r.cssText; }).join('\n'));
      } catch (e) {
        // Ignorer les feuilles cross-origin inaccessibles
      }
    });
    return styles.filter(Boolean).join('\n');
  }

  /**
   * Prepare l'element pour l'export
   */
  function prepareElementForExport(element) {
    element.querySelectorAll('.module__actions, .icon-btn, button, [data-exclude-export]').forEach(function(el) {
      if (el.classList.contains('module__actions') || el.classList.contains('icon-btn') || el.tagName === 'BUTTON') {
        el.remove();
      }
    });

    element.querySelectorAll('[style*="display:none"]').forEach(function(el) {
      el.remove();
    });

    element.classList.add('nis2-export-standalone');
    element.style.cssText = 'width:100%;background:white;padding:20px;margin:0;display:block;opacity:1;visibility:visible;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;';
  }

  /**
   * Convertit les canvas en images PNG
   */
  async function convertCanvasesToImages(element) {
    var canvases = element.querySelectorAll('canvas');
    for (var i = 0; i < canvases.length; i++) {
      var canvas = canvases[i];
      try {
        var img = document.createElement('img');
        img.src = canvas.toDataURL('image/png');
        img.style.cssText = 'width:100%;height:auto;display:block;margin:12px 0;border:1px solid #e9ecef;border-radius:6px;';
        var parent = canvas.parentNode;
        if (parent) {
          parent.replaceChild(img, canvas);
        }
      } catch (error) {
        void 0;
      }
    }
  }

  /**
   * Genere le HTML complet autonome
   */
  function generateStandaloneHtml(contentElement, cssContent) {
    var title = tt('exportLabels.programNIS2', 'Budget Cybersécurité');
    var pdfLocale = window.CSI_i18n ? ({ fr: 'fr-FR', en: 'en-GB' })[window.CSI_i18n.getLanguage()] || 'fr-FR' : 'fr-FR';
    var date = new Date().toLocaleDateString(pdfLocale, {
      year: 'numeric',
      month: 'long',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });

    var minifiedCss = minifyCss(cssContent);

    // Build the HTML string with static structure
    // contentElement.outerHTML is from a sanitized cloned DOM
    var parts = [];
    parts.push('<!DOCTYPE html>');
    parts.push('<html lang="fr">');
    parts.push('<head>');
    parts.push('<meta charset="UTF-8">');
    parts.push('<meta name="viewport" content="width=device-width, initial-scale=1.0">');
    parts.push('<title>');
    parts.push(escapeHtmlText(title));
    parts.push(' - Export</title>');
    parts.push('<style>');
    parts.push(minifiedCss);
    parts.push('</style>');
    parts.push('<style>');
    parts.push('body{margin:0;padding:0;background:white;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:#2d3e4a}');
    parts.push('.export-header{background:white;border-bottom:2px solid #1fb8cd;padding:20px;margin-bottom:20px}');
    parts.push('.export-header h1{margin:0 0 5px 0;color:#1fb8cd;font-size:28px}');
    parts.push('.export-header p{margin:5px 0;color:#666;font-size:14px}');
    parts.push('.export-content{padding:20px;max-width:1400px;margin:0 auto}');
    parts.push('.export-footer{text-align:center;padding:20px;color:#999;font-size:12px;border-top:1px solid #e9ecef;margin-top:40px}');
    parts.push('.nav,.header,.footer,#modeBanner,.global-search{display:none !important}');
    parts.push('@media print{body{background:white}.export-header,.export-footer{page-break-inside:avoid}}');
    parts.push('</style>');
    parts.push('</head>');
    parts.push('<body>');
    parts.push('<div class="export-header">');
    parts.push('<h1>');
    parts.push(escapeHtmlText(title));
    parts.push('</h1>');
    parts.push('<p><strong>');
    parts.push(escapeHtmlText(tt('exportLabels.exportedOn', 'Exporte le:')));
    parts.push('</strong> ');
    parts.push(escapeHtmlText(date));
    parts.push('</p>');
    parts.push('<p><strong>');
    parts.push(escapeHtmlText(tt('exportLabels.normReference', 'Cyber-Assistant - NIS2')));
    parts.push('</strong></p>');
    parts.push('</div>');
    parts.push('<div class="export-content">');
    // SECURITY: contentElement is a cloned and sanitized DOM from the user's own session.
    // Export is a local download only, not served to others. Self-XSS accepted risk.
    parts.push(contentElement.outerHTML);
    parts.push('</div>');
    parts.push('<div class="export-footer">');
    parts.push('<p>');
    parts.push(escapeHtmlText(tt('exportLabels.htmlStandaloneExport', 'Export HTML autonome - Cree avec Cyber-Assistant')));
    parts.push('</p>');
    parts.push('<p>');
    parts.push(escapeHtmlText(tt('exportLabels.htmlNis2Content', 'Ce fichier contient tous les styles et donnees de la section Budget Cybersécurité')));
    parts.push('</p>');
    parts.push('</div>');
    parts.push('</body>');
    parts.push('</html>');

    return parts.join('\n');
  }

  // Résoudre window.escapeHtml à l'APPEL (et non au chargement du module) :
  // nis2-export-html.js est chargé AVANT bundle.js (qui définit window.escapeHtml),
  // donc figer la référence ici la laissait undefined → l'export NIS2 plantait.
  function escapeHtmlText(s) {
    if (typeof window.escapeHtml === 'function') return window.escapeHtml(s);
    return s == null ? '' : String(s)
      .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
  }

  /**
   * Minifie le CSS
   */
  function minifyCss(css) {
    return css
      .replace(/\/\*[\s\S]*?\*\//g, '')
      .replace(/\s+/g, ' ')
      .replace(/\s*([{};:,>+~])\s*/g, '$1')
      .trim();
  }

  /**
   * Telecharge le fichier HTML
   */
  function downloadHtml(htmlContent, filename) {
    var blob = new Blob([htmlContent], { type: 'text/html;charset=utf-8' });
    var url = window.URL.createObjectURL(blob);
    var link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    window.URL.revokeObjectURL(url);
    document.body.removeChild(link);
  }

  /**
   * Affiche une notification toast
   */
  function showToast(message, type) {
    // Deleguer au toast global si disponible
    if (typeof window.showToast2 === 'function') {
      window.showToast2(message, type);
      return;
    }
    // Fallback minimal
    type = /^[a-zA-Z0-9_-]+$/.test(type) ? type : 'info';
    var container = document.getElementById('toastContainer') || createToastContainer();
    var toast = document.createElement('div');
    toast.className = 'toast toast--' + type;
    toast.textContent = message;
    var bgColor = type === 'success' ? '#4caf50' : type === 'error' ? '#f44336' : '#1fb8cd';
    toast.style.cssText = 'padding:14px 18px;margin:10px;border-radius:6px;background:' + bgColor + ';color:white;font-size:14px;box-shadow:0 4px 6px rgba(0,0,0,0.1);animation:slideIn 0.3s ease-in;';
    container.appendChild(toast);
    setTimeout(function() {
      toast.style.animation = 'slideOut 0.3s ease-out';
      setTimeout(function() { toast.remove(); }, 300);
    }, 3000);
  }

  function createToastContainer() {
    var container = document.createElement('div');
    container.id = 'toastContainer';
    container.style.cssText = 'position:fixed;top:20px;right:20px;z-index:9999;pointer-events:none;';
    document.body.appendChild(container);
    return container;
  }

  // Ajouter les animations CSS globales si pas deja presentes
  if (!document.querySelector('style[data-export-animations]')) {
    var animStyle = document.createElement('style');
    animStyle.setAttribute('data-export-animations', 'true');
    animStyle.textContent = '@keyframes slideIn{from{transform:translateX(400px);opacity:0}to{transform:translateX(0);opacity:1}}@keyframes slideOut{from{transform:translateX(0);opacity:1}to{transform:translateX(400px);opacity:0}}';
    document.head.appendChild(animStyle);
  }

  // Exposer la fonction globalement
  window.exportNis2Html = exportNis2Html;
})();
