// ScoreMethodologyModal — explique en clair comment le score d'investissement /100 est calculé.
// Objectif : lever la perception « boîte noire » en exposant les critères et leur pondération.
// Source des chiffres : docs/score-calibration-2026-05-09.md + poids du profil par défaut
// (cash_flow_long_term) dans immobilier/analysis/profiles. Aucune valeur inventée.
//
// Usage :
//   <ScoreMethodologyTrigger lang="fr" />        ← petit déclencheur « ? » qui ouvre le modal
//   <ScoreMethodologyModal open onClose={...} lang="fr" />   ← modal contrôlé (si besoin manuel)
//
// Style aligné sur PaywallModal.jsx (backdrop, panneau, animations, variables CSS).

(function () {
  const { useEffect: useSMME, useState: useSMMS } = React;

  // ---- Critères du score, avec pondération du profil par défaut (cash_flow_long_term) ----
  // Les poids varient selon le profil d'investisseur choisi, mais ces 5 axes sont constants.
  // Chiffres : cap_rate 30 %, dscr 30 %, cash_on_cash 20 %, expense_ratio 10 %, data_confidence 10 %.
  const CRITERIA = [
    {
      label: 'Rendement brut (TGA / cap rate)',
      weight: 30,
      desc: 'Revenus nets d\'opération rapportés au prix. Plus le rendement est élevé, mieux c\'est. Un TGA autour de 4 % correspond à la moyenne du marché québécois.',
    },
    {
      label: 'Couverture de la dette (DSCR)',
      weight: 30,
      desc: 'Capacité des loyers à rembourser l\'hypothèque. Un DSCR ≥ 1,2 est confortable ; sous 1,0, les revenus ne couvrent plus le service de la dette.',
    },
    {
      label: 'Rendement sur la mise de fonds (cash-on-cash)',
      weight: 20,
      desc: 'Argent qui reste dans vos poches chaque année, rapporté au comptant investi. On valorise un cash-flow positif, on pénalise progressivement le négatif.',
    },
    {
      label: 'Ratio de dépenses (OpEx / revenus)',
      weight: 10,
      desc: 'Part des revenus absorbée par les charges d\'opération. Cible sous 55 % : plus le ratio est bas, plus le bien est efficient.',
    },
    {
      label: 'Confiance dans les données',
      weight: 10,
      desc: 'Qualité et complétude des informations de l\'annonce (loyers et dépenses déclarés vs estimés). Une annonce incomplète plafonne le score plutôt que de le gonfler.',
    },
  ];

  function CloseIcon() {
    return (
      <svg width="14" height="14" viewBox="0 0 14 14" stroke="currentColor" strokeWidth="1.5" fill="none" aria-hidden="true">
        <path d="M2 2l10 10M12 2L2 12"/>
      </svg>
    );
  }

  function GaugeIcon() {
    return (
      <svg
        width="26" height="26" viewBox="0 0 24 24" fill="none"
        stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"
        style={{ display: 'block' }}
        aria-hidden="true"
      >
        <path d="M12 14l3.5-3.5"/>
        <path d="M4 18a8 8 0 1 1 16 0"/>
        <circle cx="12" cy="14" r="1.2" fill="currentColor" stroke="none"/>
      </svg>
    );
  }

  // ---- Modal ----
  function ScoreMethodologyModal({ open, onClose, lang = 'fr' }) {
    const fr = lang !== 'en';

    // Fermeture par Echap
    useSMME(() => {
      if (!open) return;
      const handleKey = (e) => { if (e.key === 'Escape') onClose(); };
      document.addEventListener('keydown', handleKey);
      return () => document.removeEventListener('keydown', handleKey);
    }, [open, onClose]);

    // Bloquer scroll body
    useSMME(() => {
      if (open) {
        document.body.style.overflow = 'hidden';
      } else {
        document.body.style.overflow = '';
      }
      return () => { document.body.style.overflow = ''; };
    }, [open]);

    if (!open) return null;

    const title = fr ? 'Comment ce score est calculé ?' : 'How is this score calculated?';
    const intro = fr
      ? 'Le score sur 100 résume la qualité d\'un bien locatif en combinant cinq critères financiers, chacun avec sa pondération. Voici la répartition pour le profil par défaut.'
      : 'The score out of 100 summarizes a rental property by combining five financial criteria, each with its own weight. Here is the breakdown for the default profile.';

    return (
      <div
        className="pw-backdrop"
        style={{
          position: 'fixed', inset: 0, zIndex: 10000,
          background: 'rgba(0, 0, 0, 0.55)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          padding: '16px',
          backdropFilter: 'blur(2px)',
          WebkitBackdropFilter: 'blur(2px)',
          animation: 'pwFadeIn 0.15s ease',
        }}
        onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
        role="dialog"
        aria-modal="true"
        aria-label={title}
      >
        <div
          className="pw-panel"
          style={{
            background: 'var(--bg-elev, #fff)',
            borderRadius: 'var(--radius-lg, 14px)',
            boxShadow: 'var(--shadow-lg, 0 20px 60px rgba(0,0,0,0.22))',
            width: '100%',
            maxWidth: 500,
            maxHeight: '88vh',
            overflowY: 'auto',
            animation: 'pwSlideUp 0.2s ease',
            fontFamily: 'var(--sans, Inter, sans-serif)',
            color: 'var(--ink-1, #1a1a1a)',
          }}
          onClick={(e) => e.stopPropagation()}
        >
          {/* ---- Header ---- */}
          <div style={{
            display: 'flex', alignItems: 'flex-start', gap: 14,
            padding: '24px 24px 0',
          }}>
            <div style={{
              flexShrink: 0,
              width: 48, height: 48, borderRadius: 12,
              background: 'var(--accent-soft, oklch(0.95 0.04 155))',
              color: 'var(--accent-ink, oklch(0.36 0.07 155))',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              marginTop: 2,
            }}>
              <GaugeIcon />
            </div>

            <div style={{ flex: 1, minWidth: 0 }}>
              <h2 style={{
                margin: '0 0 4px',
                fontFamily: 'var(--serif, Fraunces, serif)',
                fontSize: 18, fontWeight: 500,
                letterSpacing: '-0.01em',
                lineHeight: 1.3,
                color: 'var(--ink-1, #1a1a1a)',
              }}>
                {title}
              </h2>
              <p style={{
                margin: 0, fontSize: 13, lineHeight: 1.5,
                color: 'var(--ink-2, #555)',
              }}>
                {intro}
              </p>
            </div>

            <button
              onClick={onClose}
              aria-label={fr ? 'Fermer' : 'Close'}
              style={{
                flexShrink: 0,
                background: 'none', border: 'none', cursor: 'pointer',
                color: 'var(--ink-3, #999)',
                width: 28, height: 28, borderRadius: 6,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                padding: 0, marginTop: -2,
                transition: 'background 0.1s, color 0.1s',
              }}
              onMouseEnter={e => {
                e.currentTarget.style.background = 'var(--bg-warm, #f5f5f0)';
                e.currentTarget.style.color = 'var(--ink-1, #1a1a1a)';
              }}
              onMouseLeave={e => {
                e.currentTarget.style.background = 'none';
                e.currentTarget.style.color = 'var(--ink-3, #999)';
              }}
            >
              <CloseIcon />
            </button>
          </div>

          {/* ---- Liste des critères + pondération ---- */}
          <div style={{ padding: '20px 24px 0' }}>
            <ul style={{
              listStyle: 'none', padding: 0, margin: 0,
              display: 'flex', flexDirection: 'column', gap: 12,
            }}>
              {CRITERIA.map((c, i) => (
                <li key={i} style={{
                  display: 'flex', flexDirection: 'column', gap: 4,
                  paddingBottom: i < CRITERIA.length - 1 ? 12 : 0,
                  borderBottom: i < CRITERIA.length - 1 ? '1px solid var(--line, #eee)' : 'none',
                }}>
                  <div style={{
                    display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10,
                  }}>
                    <span style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-1, #1a1a1a)' }}>
                      {c.label}
                    </span>
                    <span style={{
                      flexShrink: 0,
                      display: 'inline-flex', alignItems: 'center',
                      background: 'var(--accent-soft, oklch(0.95 0.04 155))',
                      color: 'var(--accent-ink, oklch(0.36 0.07 155))',
                      borderRadius: 20, padding: '2px 10px',
                      fontSize: 12, fontWeight: 700,
                    }}>
                      {c.weight}%
                    </span>
                  </div>
                  <span style={{ fontSize: 12.5, lineHeight: 1.45, color: 'var(--ink-2, #555)' }}>
                    {c.desc}
                  </span>
                </li>
              ))}
            </ul>
          </div>

          {/* ---- Note méthodologique ---- */}
          <div style={{
            margin: '18px 24px 0',
            padding: '12px 14px',
            background: 'var(--bg-warm, #f9f9f6)',
            borderRadius: 8,
            border: '1px solid var(--line, #e8e8e0)',
            fontSize: 12, color: 'var(--ink-2, #555)', lineHeight: 1.55,
          }}>
            {fr ? (
              <>
                Les pondérations ci-dessus sont celles du profil par défaut. <strong>Elles s'ajustent
                selon le profil d'investisseur choisi</strong> (premier acheteur, chasseur de cashflow,
                value-add…) : par exemple, un premier acheteur met davantage de poids sur la couverture
                de la dette. Chaque critère est normalisé sur les données réelles du marché québécois,
                puis combiné selon ces poids pour donner la note finale sur 100.
              </>
            ) : (
              <>
                The weights above are for the default profile. <strong>They adjust based on the chosen
                investor profile</strong> (first buyer, cashflow hunter, value-add…): for instance, a
                first buyer puts more weight on debt coverage. Each criterion is normalized against real
                Quebec market data, then combined using these weights to produce the final score out of 100.
              </>
            )}
          </div>

          {/* ---- Action ---- */}
          <div style={{ padding: '20px 24px 24px' }}>
            <button
              onClick={onClose}
              style={{
                width: '100%', padding: '12px 16px',
                borderRadius: 'var(--radius, 8px)', border: 'none',
                background: 'var(--accent, oklch(0.36 0.07 155))',
                color: 'var(--accent-fg, #fff)',
                fontWeight: 600, fontSize: 14,
                cursor: 'pointer', fontFamily: 'inherit',
                letterSpacing: '-0.01em',
                transition: 'opacity 0.15s',
              }}
              onMouseEnter={e => { e.currentTarget.style.opacity = '0.88'; }}
              onMouseLeave={e => { e.currentTarget.style.opacity = '1'; }}
            >
              {fr ? 'Compris' : 'Got it'}
            </button>
          </div>

          {/* Animations réutilisées de PaywallModal (pwFadeIn / pwSlideUp déjà injectées) ;
              ré-injection inoffensive si ce modal s'ouvre en premier. */}
          <style>{`
            @keyframes pwFadeIn { from { opacity: 0; } to { opacity: 1; } }
            @keyframes pwSlideUp {
              from { transform: translateY(10px); opacity: 0; }
              to   { transform: translateY(0);    opacity: 1; }
            }
          `}</style>
        </div>
      </div>
    );
  }

  // ---- Déclencheur réutilisable : petite pastille « ? » qui ouvre le modal ----
  function ScoreMethodologyTrigger({ lang = 'fr', size = 18, style = {} }) {
    const [open, setOpen] = useSMMS(false);
    const fr = lang !== 'en';
    const aria = fr ? 'Comment ce score est calculé ?' : 'How is this score calculated?';

    return (
      <>
        <button
          type="button"
          onClick={(e) => { e.stopPropagation(); setOpen(true); }}
          aria-label={aria}
          title={aria}
          style={{
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            width: size, height: size, borderRadius: '50%',
            border: '1px solid var(--line, #d8d8d0)',
            background: 'var(--bg-elev, #fff)',
            color: 'var(--ink-3, #888)',
            fontSize: Math.round(size * 0.62), fontWeight: 700,
            lineHeight: 1, cursor: 'pointer', padding: 0,
            fontFamily: 'var(--sans, Inter, sans-serif)',
            transition: 'color 0.1s, border-color 0.1s, background 0.1s',
            ...style,
          }}
          onMouseEnter={e => {
            e.currentTarget.style.color = 'var(--accent-ink, oklch(0.36 0.07 155))';
            e.currentTarget.style.borderColor = 'var(--accent, oklch(0.36 0.07 155))';
          }}
          onMouseLeave={e => {
            e.currentTarget.style.color = 'var(--ink-3, #888)';
            e.currentTarget.style.borderColor = 'var(--line, #d8d8d0)';
          }}
        >
          ?
        </button>
        <ScoreMethodologyModal open={open} onClose={() => setOpen(false)} lang={lang} />
      </>
    );
  }

  // Exports globaux (convention du repo : composants exposés sur window)
  window.ScoreMethodologyModal = ScoreMethodologyModal;
  window.ScoreMethodologyTrigger = ScoreMethodologyTrigger;
})();
