/**
 * Cookie Banner — Embed Code Generation (CSS, HTML, JS)
 *
 * Generates the embeddable cookie banner code from configuration.
 */

import {
  CookieBannerConfig,
  CookieBannerStyling,
  CookieBannerEmbedCode,
  LocalizedText,
  SupportedLanguage,
} from '../types'

// =============================================================================
// MAIN EXPORT
// =============================================================================

export function generateEmbedCode(
  config: CookieBannerConfig,
  privacyPolicyUrl: string = '/datenschutz'
): CookieBannerEmbedCode {
  const css = generateCSS(config.styling)
  const html = generateHTML(config, privacyPolicyUrl)
  const js = generateJS(config)

  const scriptTag = `<script src="/cookie-banner.js" data-tenant="${config.tenantId}"></script>`

  return { html, css, js, scriptTag }
}

// =============================================================================
// CSS GENERATION
// =============================================================================

function generateCSS(styling: CookieBannerStyling): string {
  const positionStyles: Record<string, string> = {
    BOTTOM: 'bottom: 0; left: 0; right: 0;',
    TOP: 'top: 0; left: 0; right: 0;',
    CENTER: 'top: 50%; left: 50%; transform: translate(-50%, -50%);',
  }

  const isDark = styling.theme === 'DARK'
  const bgColor = isDark ? '#1e293b' : styling.backgroundColor || '#ffffff'
  const textColor = isDark ? '#f1f5f9' : styling.textColor || '#1e293b'
  const borderColor = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)'

  return `
/* Cookie Banner Styles */
.cookie-banner-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 9998;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
}

.cookie-banner-overlay.active {
  opacity: 1;
  visibility: visible;
}

.cookie-banner {
  position: fixed;
  ${positionStyles[styling.position]}
  z-index: 9999;
  background: ${bgColor};
  color: ${textColor};
  border-radius: ${styling.borderRadius || 12}px;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.1);
  padding: 24px;
  max-width: ${styling.maxWidth}px;
  margin: ${styling.position === 'CENTER' ? '0' : '16px'};
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  transform: translateY(100%);
  opacity: 0;
  transition: all 0.3s ease;
}

.cookie-banner.active {
  transform: translateY(0);
  opacity: 1;
}

.cookie-banner-title {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 12px;
}

.cookie-banner-description {
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 16px;
  opacity: 0.8;
}

.cookie-banner-buttons {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.cookie-banner-btn {
  flex: 1;
  min-width: 120px;
  padding: 12px 20px;
  border-radius: ${(styling.borderRadius || 12) / 2}px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  border: none;
}

.cookie-banner-btn-primary {
  background: ${styling.primaryColor};
  color: white;
}

.cookie-banner-btn-primary:hover {
  filter: brightness(1.1);
}

.cookie-banner-btn-secondary {
  background: ${styling.secondaryColor || borderColor};
  color: ${textColor};
}

.cookie-banner-btn-secondary:hover {
  filter: brightness(0.95);
}

.cookie-banner-link {
  display: block;
  margin-top: 16px;
  font-size: 12px;
  color: ${styling.primaryColor};
  text-decoration: none;
}

.cookie-banner-link:hover {
  text-decoration: underline;
}

/* Category Details */
.cookie-banner-details {
  margin-top: 16px;
  border-top: 1px solid ${borderColor};
  padding-top: 16px;
  display: none;
}

.cookie-banner-details.active {
  display: block;
}

.cookie-banner-category {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid ${borderColor};
}

.cookie-banner-category:last-child {
  border-bottom: none;
}

.cookie-banner-category-info {
  flex: 1;
}

.cookie-banner-category-name {
  font-weight: 500;
  font-size: 14px;
}

.cookie-banner-category-desc {
  font-size: 12px;
  opacity: 0.7;
  margin-top: 4px;
}

.cookie-banner-toggle {
  position: relative;
  width: 48px;
  height: 28px;
  background: ${borderColor};
  border-radius: 14px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.cookie-banner-toggle.active {
  background: ${styling.primaryColor};
}

.cookie-banner-toggle.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.cookie-banner-toggle::after {
  content: '';
  position: absolute;
  top: 4px;
  left: 4px;
  width: 20px;
  height: 20px;
  background: white;
  border-radius: 50%;
  transition: all 0.2s ease;
}

.cookie-banner-toggle.active::after {
  left: 24px;
}

@media (max-width: 640px) {
  .cookie-banner {
    margin: 0;
    border-radius: ${styling.position === 'CENTER' ? (styling.borderRadius || 12) : 0}px;
    max-width: 100%;
  }

  .cookie-banner-buttons {
    flex-direction: column;
  }

  .cookie-banner-btn {
    width: 100%;
  }
}
`.trim()
}

// =============================================================================
// HTML GENERATION
// =============================================================================

function generateHTML(config: CookieBannerConfig, privacyPolicyUrl: string): string {
  const categoriesHTML = config.categories
    .map((cat) => {
      const isRequired = cat.isRequired
      // COMPLIANCE: Only "required" categories may be pre-enabled (EuGH Planet49)
      // Non-required categories must NEVER be defaultEnabled
      const isEnabled = isRequired ? true : false
      return `
      <div class="cookie-banner-category" data-category="${cat.id}">
        <div class="cookie-banner-category-info">
          <div class="cookie-banner-category-name">${cat.name.de}</div>
          <div class="cookie-banner-category-desc">${cat.description.de}</div>
        </div>
        <div class="cookie-banner-toggle ${isEnabled ? 'active' : ''} ${isRequired ? 'disabled' : ''}"
             data-category="${cat.id}"
             data-required="${isRequired}"></div>
      </div>
    `
    })
    .join('')

  return `
<div class="cookie-banner-overlay" id="cookieBannerOverlay"></div>
<div class="cookie-banner" id="cookieBanner" role="dialog" aria-labelledby="cookieBannerTitle" aria-modal="true">
  <div class="cookie-banner-title" id="cookieBannerTitle">${config.texts.title.de}</div>
  <div class="cookie-banner-description">${config.texts.description.de}</div>

  <div class="cookie-banner-buttons">
    <button class="cookie-banner-btn cookie-banner-btn-secondary" id="cookieBannerReject">
      ${config.texts.rejectAll.de}
    </button>
    <button class="cookie-banner-btn cookie-banner-btn-secondary" id="cookieBannerCustomize">
      ${config.texts.customize.de}
    </button>
    <button class="cookie-banner-btn cookie-banner-btn-primary" id="cookieBannerAccept">
      ${config.texts.acceptAll.de}
    </button>
  </div>

  <div class="cookie-banner-details" id="cookieBannerDetails">
    ${categoriesHTML}
    <div class="cookie-banner-buttons" style="margin-top: 16px;">
      <button class="cookie-banner-btn cookie-banner-btn-primary" id="cookieBannerSave">
        ${config.texts.save.de}
      </button>
    </div>
  </div>

  <div class="cookie-banner-links">
    <a href="${privacyPolicyUrl}" class="cookie-banner-link" target="_blank">
      ${config.texts.privacyPolicyLink.de}
    </a>
    <a href="${config.impressumUrl || '/impressum'}" class="cookie-banner-link" target="_blank">
      Impressum
    </a>
  </div>
</div>

<!-- Cookie Settings Re-Open (§7(3) DSGVO — Widerruf so einfach wie Einwilligung) -->
<a href="#" id="cookieBannerReopen" class="cookie-settings-footer-link"
   onclick="document.getElementById('cookieBanner').style.display='block';document.getElementById('cookieBannerOverlay').classList.add('active');return false;"
   style="position:fixed;bottom:8px;left:8px;z-index:9990;font-size:11px;color:#6b7280;text-decoration:none;background:rgba(255,255,255,0.9);padding:4px 8px;border-radius:4px;border:1px solid #e5e7eb;">
  Cookie-Einstellungen
</a>
`.trim()
}

// =============================================================================
// JS GENERATION
// =============================================================================

function generateJS(config: CookieBannerConfig): string {
  const categoryIds = config.categories.map((c) => c.id)
  const requiredCategories = config.categories.filter((c) => c.isRequired).map((c) => c.id)

  return `
(function() {
  'use strict';

  const COOKIE_NAME = 'cookie_consent';
  const COOKIE_EXPIRY_DAYS = 365;
  const CATEGORIES = ${JSON.stringify(categoryIds)};
  const REQUIRED_CATEGORIES = ${JSON.stringify(requiredCategories)};

  // Google Consent Mode v2 — PFLICHT seit Maerz 2024 fuer Google Services
  // in EEA. Shim gtag/dataLayer falls Google Tag noch nicht initialisiert
  // wurde, dann sofort den default consent state setzen (DENIED).
  window.dataLayer = window.dataLayer || [];
  if (typeof gtag !== 'function') {
    window.gtag = function () { window.dataLayer.push(arguments); };
  }
  // wait_for_update gibt dem Banner 500ms Zeit, damit der Nutzer
  // entscheiden kann bevor Tags feuern. Empfehlung von Google fuer GCM v2.
  gtag('consent', 'default', {
    analytics_storage: 'denied',
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    functionality_storage: 'granted',
    security_storage: 'granted',
    wait_for_update: 500,
    region: ['EEA', 'CH', 'GB'],
  });

  function updateGoogleConsentMode(consent) {
    if (typeof gtag !== 'function') return;
    gtag('consent', 'update', {
      analytics_storage: consent.statistics ? 'granted' : 'denied',
      ad_storage: consent.marketing ? 'granted' : 'denied',
      ad_user_data: consent.marketing ? 'granted' : 'denied',
      ad_personalization: consent.marketing ? 'granted' : 'denied',
    });
  }

  function getConsent() {
    const cookie = document.cookie.split('; ').find(row => row.startsWith(COOKIE_NAME + '='));
    if (!cookie) return null;
    try {
      return JSON.parse(decodeURIComponent(cookie.split('=')[1]));
    } catch {
      return null;
    }
  }

  function saveConsent(consent) {
    const date = new Date();
    date.setTime(date.getTime() + (COOKIE_EXPIRY_DAYS * 24 * 60 * 60 * 1000));
    document.cookie = COOKIE_NAME + '=' + encodeURIComponent(JSON.stringify(consent)) +
                      ';expires=' + date.toUTCString() +
                      ';path=/;SameSite=Lax';
    // Append to local history (Art. 7(3) DSGVO Best-Practice + Borlabs-Parity).
    // Server-seitiges Logging laeuft separat via consent-service.
    try {
      const HKEY = COOKIE_NAME + '_history';
      const hist = JSON.parse(localStorage.getItem(HKEY) || '[]');
      hist.push({
        ts: new Date().toISOString(),
        choices: consent,
      });
      if (hist.length > 50) hist.splice(0, hist.length - 50);
      localStorage.setItem(HKEY, JSON.stringify(hist));
    } catch (e) { /* localStorage blocked */ }
    window.dispatchEvent(new CustomEvent('cookieConsentUpdated', { detail: consent }));
    updateGoogleConsentMode(consent);
  }

  // Borlabs-Parity: zeigt dem Nutzer alle seine bisherigen Einwilligungen.
  // Aufruf via window.bpShowConsentHistory() oder Klick auf den Link im Banner-Footer.
  window.bpShowConsentHistory = function () {
    var existing = document.getElementById('bpConsentHistoryModal');
    if (existing) { existing.remove(); return; }
    var hist = [];
    try { hist = JSON.parse(localStorage.getItem(COOKIE_NAME + '_history') || '[]'); } catch (e) {}
    var rows = hist.length === 0
      ? '<p style="color:#94a3b8;font-style:italic">Noch keine Einwilligungen gespeichert.</p>'
      : hist.slice().reverse().map(function (h) {
          var d = new Date(h.ts);
          var parts = Object.keys(h.choices).map(function (k) {
            return '<span style="margin-right:8px;font-size:11px;color:' +
              (h.choices[k] ? '#16a34a' : '#dc2626') + '">' +
              (h.choices[k] ? '✓ ' : '✗ ') + k + '</span>';
          }).join('');
          return '<div style="border-bottom:1px solid #e5e7eb;padding:8px 0">' +
                 '<div style="font-size:12px;color:#64748b;margin-bottom:4px">' +
                 d.toLocaleString('de-DE') + '</div>' +
                 '<div>' + parts + '</div></div>';
        }).join('');
    var modal = document.createElement('div');
    modal.id = 'bpConsentHistoryModal';
    modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.5);' +
      'z-index:999999;display:flex;align-items:center;justify-content:center;padding:20px';
    modal.innerHTML = '<div style="background:white;border-radius:8px;max-width:500px;' +
      'width:100%;max-height:80vh;overflow:auto;padding:20px;font-family:-apple-system,sans-serif">' +
      '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">' +
      '<h3 style="margin:0;font-size:16px">Ihre Einwilligungs-Historie</h3>' +
      '<button onclick="document.getElementById(\\'bpConsentHistoryModal\\').remove()" ' +
      'style="background:none;border:none;font-size:24px;cursor:pointer;color:#94a3b8">×</button>' +
      '</div>' +
      '<p style="font-size:12px;color:#64748b;margin:0 0 12px">' +
      'Lokal in Ihrem Browser gespeichert. Server-seitig laufen Audit-Logs gemaess Art. 7(1) DSGVO.</p>' +
      rows + '</div>';
    modal.addEventListener('click', function (e) { if (e.target === modal) modal.remove(); });
    document.body.appendChild(modal);
  };

  function hasConsent(category) {
    const consent = getConsent();
    if (!consent) return REQUIRED_CATEGORIES.includes(category);
    return consent[category] === true;
  }

  function initBanner() {
    const banner = document.getElementById('cookieBanner');
    const overlay = document.getElementById('cookieBannerOverlay');
    const details = document.getElementById('cookieBannerDetails');

    if (!banner) return;

    const consent = getConsent();
    if (consent) return;

    setTimeout(() => {
      banner.classList.add('active');
      overlay.classList.add('active');
    }, 500);

    document.getElementById('cookieBannerAccept')?.addEventListener('click', () => {
      const consent = {};
      CATEGORIES.forEach(cat => consent[cat] = true);
      saveConsent(consent);
      closeBanner();
    });

    document.getElementById('cookieBannerReject')?.addEventListener('click', () => {
      const consent = {};
      CATEGORIES.forEach(cat => consent[cat] = REQUIRED_CATEGORIES.includes(cat));
      saveConsent(consent);
      closeBanner();
    });

    document.getElementById('cookieBannerCustomize')?.addEventListener('click', () => {
      details.classList.toggle('active');
    });

    document.getElementById('cookieBannerSave')?.addEventListener('click', () => {
      const consent = {};
      CATEGORIES.forEach(cat => {
        const toggle = document.querySelector('.cookie-banner-toggle[data-category="' + cat + '"]');
        consent[cat] = toggle?.classList.contains('active') || REQUIRED_CATEGORIES.includes(cat);
      });
      saveConsent(consent);
      closeBanner();
    });

    document.querySelectorAll('.cookie-banner-toggle').forEach(toggle => {
      if (toggle.dataset.required === 'true') return;
      toggle.addEventListener('click', () => {
        toggle.classList.toggle('active');
      });
    });

    overlay?.addEventListener('click', () => {
      // Don't close - user must make a choice
    });
  }

  function closeBanner() {
    const banner = document.getElementById('cookieBanner');
    const overlay = document.getElementById('cookieBannerOverlay');
    banner?.classList.remove('active');
    overlay?.classList.remove('active');
  }

  // Script-Blocking: activate scripts with data-cookie-category ONLY after consent
  function activateConsentedScripts() {
    const consent = getConsent();
    if (!consent) return;

    // Find all blocked scripts (type="text/plain" with data-cookie-category)
    document.querySelectorAll('script[data-cookie-category][type="text/plain"]').forEach(script => {
      const category = script.getAttribute('data-cookie-category');
      if (consent[category] === true) {
        // Replace type to activate the script
        const newScript = document.createElement('script');
        if (script.src) newScript.src = script.src;
        else newScript.textContent = script.textContent;
        newScript.type = 'text/javascript';
        script.parentNode.replaceChild(newScript, script);
      }
    });

    // Also fire custom event for programmatic listeners
    window.dispatchEvent(new CustomEvent('cookieConsentActivated', { detail: consent }));
  }

  // Run script activation after consent is saved
  window.addEventListener('cookieConsentUpdated', activateConsentedScripts);

  window.CookieConsent = {
    getConsent,
    saveConsent,
    hasConsent,
    show: () => {
      document.getElementById('cookieBanner')?.classList.add('active');
      document.getElementById('cookieBannerOverlay')?.classList.add('active');
    },
    hide: closeBanner,
    activateScripts: activateConsentedScripts,
  };

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
      initBanner();
      activateConsentedScripts();
    });
  } else {
    initBanner();
    activateConsentedScripts();
  }
})();

/*
 * USAGE: Script-Blocking
 *
 * Instead of:
 *   <script src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXX"></script>
 *
 * Use:
 *   <script type="text/plain" data-cookie-category="statistics"
 *           src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXX"></script>
 *
 * The script will only execute AFTER the user consents to "statistics".
 */
`.trim()
}
