/* global React */
// ============================================================================
// guided-tour.jsx — Tour guidé de première visite
// ----------------------------------------------------------------------------
// Composant léger sans dépendance externe (pas d'Intro.js / Shepherd / etc.).
// 8 étapes qui guident l'utilisateur à travers les modules clés :
//   1. Bienvenue (centré)
//   2. La barre latérale
//   3. La recherche globale (Cmd+K)
//   4. Le tableau de bord
//   5. Les projets
//   6. Les indicateurs
//   7. Le reporting
//   8. L'aide
//
// Auto-launch : si localStorage["melr.tour.completed.v1"] n'est pas "1",
// le tour démarre 1 seconde après le mount de l'app.
//
// Manual launch : via `window.MELRTour.start()` (exposé global, branché
// depuis l'écran Aide via un bouton "Relancer le tour").
//
// Persistance : à la fin (ou skip), localStorage est marqué. La version
// v1 est incluse dans la clé pour qu'on puisse relancer le tour quand
// on ajoute de nouveaux modules (passer à v2).
// ============================================================================

(function () {
  "use strict";

  const STORAGE_KEY = "melr.tour.completed.v1";

  // Définition des étapes — bilingue. Chaque étape a optionnellement :
  // - selector : CSS pour highlight l'élément cible
  // - route    : route à activer avant d'afficher (via window.__navigate)
  // - position : "top" | "bottom" | "left" | "right" | "center" (défaut bottom)
  function buildSteps(lang) {
    const T = (fr, en) => (lang === "fr" ? fr : en);
    return [
      {
        title: T("Bienvenue dans MELR 👋", "Welcome to MELR 👋"),
        body:  T(
          "Une visite rapide en 8 étapes pour découvrir les modules clés. Vous pouvez passer à tout moment et la relancer depuis l'Aide.",
          "A quick 8-step tour to discover the key modules. You can skip anytime and relaunch from Help."
        ),
        position: "center",
      },
      {
        title: T("La barre latérale", "The sidebar"),
        body:  T(
          "Tous les modules sont accessibles depuis le menu de gauche, code-couleur par bloc. Cliquez l'icône en haut pour la replier en mode compact.",
          "All modules are accessible from the left menu, color-coded per block. Click the top icon to collapse it into compact mode."
        ),
        selector: ".sidebar",
        position: "right",
      },
      {
        title: T("Recherche globale", "Global search"),
        body:  T(
          "Appuyez Cmd+K (ou Ctrl+K) n'importe où pour chercher un projet, indicateur, activité ou site. La même barre dans le topbar fait pareil.",
          "Press Cmd+K (or Ctrl+K) anywhere to search projects, indicators, activities or sites. The topbar button does the same."
        ),
        selector: ".search-trigger",
        position: "bottom",
      },
      {
        title: T("Tableau de bord", "Dashboard"),
        route: "dashboard",
        body:  T(
          "Vue d'ensemble du portefeuille : KPIs, breakdown par secteur, alertes consolidées. Le 1er écran après login.",
          "Portfolio overview: KPIs, sector breakdown, consolidated alerts. The default first screen after login."
        ),
        position: "center",
      },
      {
        title: T("Projets", "Projects"),
        route: "projects",
        body:  T(
          "Liste filtrable de votre portefeuille. Cliquez un projet pour drill-down : objectifs, ToC, Gantt, indicateurs, sites, budget, équipe, etc.",
          "Filterable portfolio list. Click a project to drill down: objectives, ToC, Gantt, indicators, sites, budget, team, etc."
        ),
        position: "center",
      },
      {
        title: T("Indicateurs", "Indicators"),
        route: "indicators",
        body:  T(
          "Le module Indicateurs comporte 2 sous-écrans : « Définition » (catalogue org-wide) et « Suivi » (saisie de valeurs). Importez en Excel ou créez à la main.",
          "Indicators has 2 sub-screens: 'Definitions' (org catalog) and 'Tracking' (value entry). Import from Excel or create manually."
        ),
        position: "center",
      },
      {
        title: T("Reporting", "Reporting"),
        route: "reporting",
        body:  T(
          "2 onglets : Indicateurs (rapports périodiques) + Activités (vue analytique multi-projets). Exports CSV / Excel / PDF / Word.",
          "2 tabs: Indicators (periodic reports) + Activities (analytical multi-project view). CSV / Excel / PDF / Word exports."
        ),
        position: "center",
      },
      {
        title: T("L'aide est toujours là", "Help is always there"),
        route: "help",
        body:  T(
          "Documentation complète + FAQ + formulaire de bug/suggestion. Activez aussi la 2FA depuis votre profil pour sécuriser votre compte.",
          "Full docs + FAQ + bug/suggestion ticket form. Also enable 2FA from your profile to secure your account."
        ),
        position: "center",
      },
    ];
  }

  // ── Composant React ──────────────────────────────────────────────────
  function GuidedTour({ lang, onClose }) {
    const { useState, useEffect, useRef } = React;
    const steps = buildSteps(lang);
    const [stepIdx, setStepIdx] = useState(0);
    const [targetRect, setTargetRect] = useState(null);
    const step = steps[stepIdx];

    // Quand l'étape change : naviguer si nécessaire, puis trouver l'élément
    // cible et calculer son rect après un court délai (le temps que le DOM
    // se mette à jour).
    useEffect(() => {
      let cancelled = false;
      if (step.route && window.__navigate) {
        try { window.__navigate(step.route); } catch (_) {}
      }
      setTargetRect(null);
      if (!step.selector) return;
      const findTarget = () => {
        if (cancelled) return;
        const el = document.querySelector(step.selector);
        if (el) {
          try { el.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" }); } catch (_) {}
          // Re-mesure après le scroll
          setTimeout(() => {
            if (cancelled) return;
            const rect = el.getBoundingClientRect();
            setTargetRect(rect);
          }, 350);
        } else {
          // Élément pas encore monté — retenter dans 200ms (max 5 fois)
          if (findTarget.tries == null) findTarget.tries = 0;
          if (findTarget.tries < 5) { findTarget.tries += 1; setTimeout(findTarget, 200); }
        }
      };
      const t = setTimeout(findTarget, step.route ? 400 : 100);
      return () => { cancelled = true; clearTimeout(t); };
    }, [stepIdx]);

    // Esc / ← / → pour navigation clavier
    useEffect(() => {
      const onKey = (e) => {
        if (e.key === "Escape") { onClose(true); }
        else if (e.key === "ArrowRight" || e.key === "Enter") {
          if (stepIdx < steps.length - 1) setStepIdx(stepIdx + 1);
          else onClose(false);
        } else if (e.key === "ArrowLeft" && stepIdx > 0) {
          setStepIdx(stepIdx - 1);
        }
      };
      document.addEventListener("keydown", onKey);
      return () => document.removeEventListener("keydown", onKey);
    }, [stepIdx, steps.length]);

    // Position de la tooltip : si targetRect existe, basée dessus ; sinon
    // centrée. Choix top/bottom/left/right selon "position" + espace dispo.
    const tooltipStyle = (() => {
      const base = {
        position: "fixed",
        zIndex: 10001,
        background: "var(--bg, white)",
        color: "var(--text)",
        borderRadius: 10,
        padding: "16px 18px",
        boxShadow: "0 20px 60px rgba(0,0,0,0.3)",
        border: "1px solid var(--line)",
        maxWidth: 380,
        width: "calc(100vw - 32px)",
      };
      if (!targetRect || step.position === "center") {
        return { ...base, top: "50%", left: "50%", transform: "translate(-50%, -50%)" };
      }
      const pos = step.position || "bottom";
      const M = 12; // marge entre target et tooltip
      const VH = window.innerHeight, VW = window.innerWidth;
      if (pos === "bottom") {
        const top = targetRect.bottom + M;
        if (top + 200 < VH) return { ...base, top, left: Math.min(VW - 400, Math.max(16, targetRect.left)) };
      }
      if (pos === "top") {
        const bottom = VH - targetRect.top + M;
        return { ...base, bottom, left: Math.min(VW - 400, Math.max(16, targetRect.left)) };
      }
      if (pos === "right") {
        const left = targetRect.right + M;
        if (left + 380 < VW) return { ...base, top: Math.max(16, targetRect.top), left };
      }
      if (pos === "left") {
        const right = VW - targetRect.left + M;
        return { ...base, top: Math.max(16, targetRect.top), right };
      }
      // Fallback : centré
      return { ...base, top: "50%", left: "50%", transform: "translate(-50%, -50%)" };
    })();

    const T = (fr, en) => (lang === "fr" ? fr : en);

    return (
      <>
        {/* Backdrop avec « cut-out » autour de la cible (effet spotlight) */}
        <div
          onClick={() => onClose(true)}
          style={{
            position: "fixed", inset: 0, zIndex: 10000,
            background: "rgba(0,0,0,0.55)",
            pointerEvents: "auto",
            transition: "opacity 200ms ease",
          }}
        />
        {/* Highlight rectangle autour de la cible (ombre intérieure + bordure) */}
        {targetRect && (
          <div
            style={{
              position: "fixed", zIndex: 10000,
              top: targetRect.top - 6,
              left: targetRect.left - 6,
              width: targetRect.width + 12,
              height: targetRect.height + 12,
              borderRadius: 8,
              border: "2px solid var(--accent, #4f46e5)",
              boxShadow: "0 0 0 9999px rgba(0,0,0,0.55), 0 0 30px var(--accent, #4f46e5)",
              pointerEvents: "none",
              transition: "all 250ms cubic-bezier(0.4, 0, 0.2, 1)",
            }}
          />
        )}

        {/* Tooltip */}
        <div style={tooltipStyle} role="dialog" aria-label="Tour guidé">
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 10 }}>
            <span style={{
              fontSize: 10.5, fontWeight: 700, color: "var(--text-faint)",
              textTransform: "uppercase", letterSpacing: "0.08em",
            }}>
              {stepIdx + 1} / {steps.length}
            </span>
            <button onClick={() => onClose(true)}
              style={{ background: "transparent", border: 0, cursor: "pointer", color: "var(--text-faint)", fontSize: 18, lineHeight: 1 }}
              aria-label={T("Fermer", "Close")}>
              ×
            </button>
          </div>

          <div style={{ fontSize: 16, fontWeight: 600, marginBottom: 8 }}>{step.title}</div>
          <div style={{ fontSize: 13, lineHeight: 1.5, color: "var(--text)", marginBottom: 16 }}>{step.body}</div>

          {/* Petite barre de progression */}
          <div style={{ height: 3, background: "var(--bg-sunken)", borderRadius: 2, marginBottom: 14, overflow: "hidden" }}>
            <div style={{
              height: "100%",
              width: ((stepIdx + 1) / steps.length * 100) + "%",
              background: "var(--accent, #4f46e5)",
              transition: "width 250ms ease",
            }} />
          </div>

          <div style={{ display: "flex", gap: 8, justifyContent: "space-between", alignItems: "center" }}>
            <button onClick={() => onClose(true)}
              style={{
                fontSize: 12, padding: "6px 10px",
                background: "transparent", border: 0, color: "var(--text-faint)",
                cursor: "pointer",
              }}>
              {T("Passer le tour", "Skip tour")}
            </button>
            <div style={{ display: "flex", gap: 6 }}>
              <button onClick={() => setStepIdx(stepIdx - 1)} disabled={stepIdx === 0}
                style={{
                  fontSize: 12, padding: "6px 12px",
                  background: "transparent",
                  border: "1px solid var(--line)",
                  color: stepIdx === 0 ? "var(--text-faint)" : "var(--text)",
                  borderRadius: 5, cursor: stepIdx === 0 ? "not-allowed" : "pointer",
                  opacity: stepIdx === 0 ? 0.4 : 1,
                }}>
                ← {T("Précédent", "Previous")}
              </button>
              <button onClick={() => {
                if (stepIdx < steps.length - 1) setStepIdx(stepIdx + 1);
                else onClose(false);
              }}
                style={{
                  fontSize: 12, padding: "6px 14px",
                  background: "var(--accent, #4f46e5)", color: "white",
                  border: 0, borderRadius: 5, cursor: "pointer", fontWeight: 600,
                }}>
                {stepIdx < steps.length - 1 ? T("Suivant", "Next") + " →" : T("Terminer ✓", "Finish ✓")}
              </button>
            </div>
          </div>
        </div>
      </>
    );
  }

  // ── Wrapper : monte/démonte le composant + persistance ───────────────
  let currentRoot = null;
  let currentContainer = null;

  function start(lang) {
    if (currentRoot) return; // déjà en cours
    const detectLang = lang || (document.documentElement.lang === "en" ? "en" : "fr");
    currentContainer = document.createElement("div");
    currentContainer.id = "melr-guided-tour";
    document.body.appendChild(currentContainer);
    const { createRoot } = window.ReactDOM;
    currentRoot = createRoot(currentContainer);
    currentRoot.render(
      React.createElement(GuidedTour, {
        lang: detectLang,
        onClose: (skipped) => {
          // Persister la complétion. On le fait même si skip car l'utilisateur
          // a choisi de ne pas voir le tour — on ne le ré-affiche pas seul.
          try { localStorage.setItem(STORAGE_KEY, skipped ? "skipped" : "1"); } catch (_) {}
          stop();
        },
      })
    );
  }

  function stop() {
    if (currentRoot) { currentRoot.unmount(); currentRoot = null; }
    if (currentContainer && currentContainer.parentNode) {
      currentContainer.parentNode.removeChild(currentContainer);
      currentContainer = null;
    }
  }

  function hasCompleted() {
    try { return !!localStorage.getItem(STORAGE_KEY); } catch (_) { return false; }
  }

  function resetCompletion() {
    try { localStorage.removeItem(STORAGE_KEY); } catch (_) {}
  }

  // Auto-launch : 2s après le chargement de la page, si pas encore complété
  // et si l'utilisateur a une sidebar visible (= loggé). Délai = laisser
  // l'app finir son boot.
  function maybeAutoStart() {
    if (hasCompleted()) return;
    setTimeout(() => {
      // Vérifie que l'app est loggée (sidebar dans le DOM)
      if (!document.querySelector(".sidebar, aside")) {
        // Pas loggé : retenter dans 3s
        setTimeout(maybeAutoStart, 3000);
        return;
      }
      // Vérifie une dernière fois (l'utilisateur a pu manuellement complete)
      if (hasCompleted()) return;
      start();
    }, 2000);
  }

  // API publique
  window.MELRTour = {
    start,
    stop,
    hasCompleted,
    resetCompletion,
    // Pour le bouton "Relancer le tour" depuis l'Aide
    relaunch(lang) { resetCompletion(); start(lang); },
  };

  // Démarrage automatique après chargement
  if (document.readyState === "complete" || document.readyState === "interactive") {
    maybeAutoStart();
  } else {
    window.addEventListener("DOMContentLoaded", maybeAutoStart);
  }
})();
