// ScoringModeToggle — toggle global "Marché" / "Standards banque" + popover pédagogique.
// État persistant dans localStorage.vestoraScoringMode.
// Émet `scoringModeChanged` quand l'utilisateur bascule.
// PR #199 — double notation (Tâche E audit chiffres Vestora).

(function() {
const STORAGE_KEY = 'vestoraScoringMode';
const VALID_MODES = ['marche', 'banque'];

function getScoringMode() {
  try {
    const v = localStorage.getItem(STORAGE_KEY);
    if (VALID_MODES.includes(v)) return v;
  } catch (e) { /* SSR / private mode */ }
  return 'marche';
}

function setScoringMode(mode) {
  if (!VALID_MODES.includes(mode)) return;
  try { localStorage.setItem(STORAGE_KEY, mode); } catch (e) { /* noop */ }
  try {
    window.dispatchEvent(new CustomEvent('scoringModeChanged', { detail: { mode } }));
  } catch (e) { /* noop */ }
}

// Récupère le score à afficher selon le mode actif, avec fallback gracieux.
function getScoreForMode(listing, mode) {
  if (!listing) return null;
  const m = listing.metrics || {};
  if (mode === 'banque') {
    if (m.scoreBanque != null) return m.scoreBanque;
    if (listing.scoreBanque != null) return listing.scoreBanque;
    return null; // pas de fallback silencieux vers marché — on veut voir l'absence
  }
  // mode 'marche' par défaut
  if (m.scoreMarche != null) return m.scoreMarche;
  if (listing.scoreMarche != null) return listing.scoreMarche;
  if (typeof listing.score === 'number') return listing.score;
  return null;
}

function getScoreLabelForMode(listing, mode) {
  const labels = (listing && listing.metrics && listing.metrics.scoreLabels) || null;
  if (!labels) return null;
  return mode === 'banque' ? labels.banque : labels.marche;
}

// True si bon score marché mais banque rejette → pictogramme divergence.
function hasScoreDivergence(listing) {
  if (!listing || !listing.metrics) return false;
  const sm = listing.metrics.scoreMarche;
  const sb = listing.metrics.scoreBanque;
  if (sm == null || sb == null) return false;
  return Math.abs(sm - sb) >= 30 && sb < 40;
}

const { useState, useEffect, useRef } = React;

function ScoringModeToggle({ size = 'md', showLabel = true, onChange }) {
  const [mode, setMode] = useState(() => getScoringMode());
  const [showHelp, setShowHelp] = useState(false);
  const [popoverPos, setPopoverPos] = useState({ top: 0, right: 0 });
  const popoverRef = useRef(null);
  const helpBtnRef = useRef(null);

  useEffect(() => {
    const onExt = (e) => {
      const m = e?.detail?.mode;
      if (VALID_MODES.includes(m) && m !== mode) setMode(m);
    };
    window.addEventListener('scoringModeChanged', onExt);
    return () => window.removeEventListener('scoringModeChanged', onExt);
  }, [mode]);

  useEffect(() => {
    if (!showHelp) return;
    // Click-outside : check sur le bouton ? ET sur le popover (qui est porté ailleurs dans le DOM)
    const onDoc = (e) => {
      const inPop = popoverRef.current && popoverRef.current.contains(e.target);
      const inBtn = helpBtnRef.current && helpBtnRef.current.contains(e.target);
      if (!inPop && !inBtn) setShowHelp(false);
    };
    const onEsc = (e) => { if (e.key === 'Escape') setShowHelp(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onEsc);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      document.removeEventListener('keydown', onEsc);
    };
  }, [showHelp]);

  // Calcule la position fixed du popover depuis le bouton "?" et reposition au scroll/resize.
  useEffect(() => {
    if (!showHelp) return;
    const compute = () => {
      const el = helpBtnRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      setPopoverPos({
        top: Math.round(rect.bottom + 8),
        right: Math.round(window.innerWidth - rect.right),
      });
    };
    compute();
    window.addEventListener('scroll', compute, true);
    window.addEventListener('resize', compute);
    return () => {
      window.removeEventListener('scroll', compute, true);
      window.removeEventListener('resize', compute);
    };
  }, [showHelp]);

  const change = (next) => {
    setMode(next);
    setScoringMode(next);
    if (typeof onChange === 'function') onChange(next);
  };

  const isSmall = size === 'sm';
  const btnH = isSmall ? 24 : 30;
  const fs = isSmall ? 11 : 12;
  const pad = isSmall ? '0 8px' : '0 12px';

  const btnStyle = (active) => ({
    height: btnH,
    padding: pad,
    fontSize: fs,
    fontWeight: 500,
    border: 'none',
    background: active ? 'var(--brand-sauge, #6b8e6b)' : 'transparent',
    color: active ? '#fff' : 'var(--ink-2, #555)',
    cursor: 'pointer',
    borderRadius: 6,
    transition: 'background 120ms, color 120ms',
    whiteSpace: 'nowrap',
  });

  return React.createElement('div', {
    className: 'scoring-mode-toggle',
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 4,
      padding: 3,
      background: 'var(--bg-warm, #f5f5f0)',
      border: '1px solid var(--line, #e8e8e0)',
      borderRadius: 8,
      position: 'relative',
      fontFamily: 'inherit',
    }
  },
    showLabel && React.createElement('span', {
      style: { fontSize: fs - 1, color: 'var(--ink-3, #888)', padding: '0 6px', whiteSpace: 'nowrap' }
    }, 'Score :'),
    React.createElement('button', {
      type: 'button',
      onClick: () => change('marche'),
      style: btnStyle(mode === 'marche'),
      'aria-pressed': mode === 'marche',
      title: 'Position relative parmi les ~8 000 annonces du marché QC actuel (2026). Cliquez ? pour comprendre.'
    }, 'Marché actuel'),
    React.createElement('button', {
      type: 'button',
      onClick: () => change('banque'),
      style: btnStyle(mode === 'banque'),
      'aria-pressed': mode === 'banque',
      title: 'Score absolu — standards banque/SCHL (DSCR ≥ 1.25, cap rate ≥ 6 %)'
    }, 'Standards banque'),
    React.createElement('button', {
      ref: helpBtnRef,
      type: 'button',
      onClick: () => setShowHelp(v => !v),
      style: {
        height: btnH - 4,
        width: btnH - 4,
        marginLeft: 2,
        marginRight: 2,
        border: '1px solid var(--line, #ddd)',
        background: '#fff',
        color: 'var(--ink-2, #555)',
        cursor: 'pointer',
        borderRadius: '50%',
        fontSize: fs - 1,
        fontWeight: 600,
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
      },
      'aria-label': 'Aide — différence entre les deux scores',
      'aria-expanded': showHelp
    }, '?'),
    showHelp && (window.ReactDOM || ReactDOM).createPortal(React.createElement('div', {
      ref: popoverRef,
      role: 'dialog',
      'aria-label': 'Aide score',
      style: {
        position: 'fixed',
        top: popoverPos.top,
        right: popoverPos.right,
        width: 360,
        maxWidth: '90vw',
        padding: '14px 16px',
        background: '#fff',
        border: '1px solid var(--line, #e8e8e0)',
        borderRadius: 10,
        boxShadow: '0 8px 24px rgba(0,0,0,0.12)',
        fontSize: 13,
        lineHeight: 1.5,
        color: 'var(--ink-1, #222)',
        zIndex: 99999,
      }
    },
      React.createElement('div', { style: { fontWeight: 600, marginBottom: 8 } }, 'Pourquoi deux notes ?'),
      React.createElement('p', { style: { margin: '6px 0' } },
        React.createElement('strong', null, 'Marché actuel'),
        ' — Position relative parmi les ~8 000 annonces QC actuelles. Utile pour ',
        React.createElement('strong', null, 'comparer entre annonces'),
        ' rapidement. Un score 75 = top quartile du marché 2026, même si la rentabilité absolue reste modeste (les taux d\'intérêt élevés ont compressé les cap rates partout).'
      ),
      React.createElement('p', { style: { margin: '6px 0' } },
        React.createElement('strong', null, 'Standards banque'),
        ' — Évaluation contre les critères de financement bancaire et SCHL. Utile pour savoir si la ',
        React.createElement('strong', null, 'banque acceptera de financer'),
        '. Un score 75 = DSCR ≥ 1.25, cash-flow positif, cap rate ≥ 6 %.'
      ),
      React.createElement('p', { style: { margin: '8px 0 0', padding: '8px 10px', background: 'var(--bg-warm, #f5f5f0)', borderLeft: '3px solid var(--brand-sauge, #6b8e6b)', borderRadius: 4, fontSize: 12 } },
        'Si un bien a un ',
        React.createElement('strong', null, 'score Marché élevé mais score Banque faible'),
        ', c\'est qu\'il est bon par rapport au reste du marché actuel mais que sa rentabilité absolue est insuffisante pour un prêt conventionnel — typique en 2026 avec les taux actuels.'
      )
    ), document.body)
  );
}

// Pictogramme divergence (triangle jaune)
function DivergenceBadge({ listing, lang = 'fr', size = 14 }) {
  if (!hasScoreDivergence(listing)) return null;
  const title = lang === 'fr'
    ? 'Bon prix relatif au marché, mais financement bancaire difficile (DSCR < 1.10).'
    : 'Good relative market price, but bank financing is difficult (DSCR < 1.10).';
  return React.createElement('span', {
    className: 'score-divergence-badge',
    title,
    'aria-label': title,
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      justifyContent: 'center',
      width: size + 4,
      height: size + 4,
      marginLeft: 4,
      color: '#b45309',
      cursor: 'help',
      verticalAlign: 'middle',
    }
  },
    React.createElement('svg', {
      width: size, height: size, viewBox: '0 0 16 16', fill: 'currentColor', 'aria-hidden': 'true'
    },
      React.createElement('path', {
        d: 'M8 1.5L15 14H1L8 1.5zM8 6v4M8 11.5v.5',
        stroke: '#b45309', strokeWidth: 1.4, fill: '#fde68a', strokeLinejoin: 'round'
      })
    )
  );
}

// Expose globalement pour les composants qui ne sont pas convertis en imports ES modules
if (typeof window !== 'undefined') {
  window.vestora = window.vestora || {};
  window.vestora.scoringMode = {
    get: getScoringMode,
    set: setScoringMode,
    getScore: getScoreForMode,
    getLabel: getScoreLabelForMode,
    hasDivergence: hasScoreDivergence,
    Toggle: ScoringModeToggle,
    DivergenceBadge: DivergenceBadge,
  };
  // Exposer aussi comme globales pour usage direct dans les composants Babel script-tag
  window.ScoringModeToggle = ScoringModeToggle;
  window.DivergenceBadge = DivergenceBadge;
}
})();
