// EtapesScreen v3 — oval circuit layout
const { useState, useEffect, useMemo, useRef } = React;

// ── Panneau "Toutes les entreprises" (partagé avec StageDetail) ──────────────
function AllCompaniesPanel({ entreprises, onClose, onPick }) {
  const [enter, setEnter] = useState(false);
  useEffect(() => { requestAnimationFrame(() => setEnter(true)); }, []);

  const unique = useMemo(() => {
    const seen = new Set();
    return entreprises
      .filter(e => { if (seen.has(e.nom)) return false; seen.add(e.nom); return true; })
      .sort((a, b) => a.nom.localeCompare(b.nom, 'fr'));
  }, [entreprises]);

  return ReactDOM.createPortal(
    <div className="all-ent-bd" onClick={onClose}>
      <div
        className="all-ent-panel"
        onClick={e => e.stopPropagation()}
        style={{
          transform: enter ? 'translateX(0)' : 'translateX(60px)',
          opacity: enter ? 1 : 0,
          transition: 'transform 360ms cubic-bezier(0.22,1,0.36,1), opacity 360ms cubic-bezier(0.22,1,0.36,1)',
        }}
      >
        <div className="all-ent-panel__header">
          <button className="entreprise__close" onClick={onClose} aria-label="Fermer">
            <span></span>
            <span></span>
          </button>
          <div className="entreprise__eyebrow">Répertoire</div>
          <h2 className="all-ent-panel__title">Toutes les entreprises</h2>
          <div className="all-ent-panel__subtitle">{unique.length} entreprise{unique.length > 1 ? 's' : ''}</div>
        </div>
        <div className="all-ent-panel__body">
          {unique.map((ent, i) => (
            <button
              key={`${ent.nom}_${i}`}
              className="all-ent-row"
              onClick={() => onPick(ent)}
            >
              <span className="all-ent-row__name">{ent.nom}</span>
              {ent.precision && <span className="all-ent-row__prec">{ent.precision}</span>}
            </button>
          ))}
        </div>
      </div>
    </div>,
    document.body
  );
}
window.AllCompaniesPanel = AllCompaniesPanel;

const RIVER_ICON_BASE = 'assets/river_icons_couleurs/';

// Oval parameters (SVG viewBox 1000×600)
// start=70 : les deux extrémités (i=0 et i=8) sont symétriques autour du sommet (α=90°),
// ce qui centre le vide en haut de la page.
// cy=280, ry=200 : conserve le bas à y=80% tout en gagnant de l'espace vers le haut.
const OV = { cx: 500, cy: 280, rx: 370, ry: 200, n: 9, step: 40, start: 70 };

// Bezier approximation factor for a circular arc segment of `step` degrees
const BKAPPA = (4 / 3) * Math.tan((OV.step / 2) * Math.PI / 180); // ≈ 0.4853

function ovalPoint(i) {
  const a = (OV.start - i * OV.step) * Math.PI / 180; // sens horaire depuis l'angle de départ
  return { x: OV.cx + OV.rx * Math.cos(a), y: OV.cy - OV.ry * Math.sin(a), a };
}

// Arrondi à la dizaine inférieure : 169 → 160, 170 → 170
function floorTen(n) { return Math.floor(n / 10) * 10; }

function CircuitLayout({ numbered, allEntreprises, totalEntreprises, onPickEtape, onPickTransversal, onPickEntreprise }) {
  const [revealedCount, setRevealedCount] = useState(0);
  const [showAllPanel, setShowAllPanel] = useState(false);

  // 9 nœuds sur un ovale ouvert (arc 320°), Bauxite centré en haut
  // Raffinage (i=1) et Recyclage (i=7) avancés de 8° vers le sommet le long de la courbe
  const angleAdjust = { 1: 8, 7: -8 };
  const positions = useMemo(() => {
    const pts = [];
    for (let i = 0; i < OV.n; i++) {
      const a = (OV.start - i * OV.step + (angleAdjust[i] || 0)) * Math.PI / 180;
      const x = OV.cx + OV.rx * Math.cos(a);
      const y = OV.cy - OV.ry * Math.sin(a);
      pts[i] = { x: x / 1000, y: y / 600 };
    }
    return pts;
  }, []);

  // Nœuds à afficher
  const displayNodes = useMemo(() => {
    function mergeCount(indices) {
      const ents = new Set();
      indices.forEach(i => numbered[i].categories.forEach(c => c.services.forEach(s => s.entreprises.forEach(e => ents.add(e.nom)))));
      return ents.size;
    }
    const clean = nom => nom.replace(/^\d+[a-z]?\.\s*/i, '');
    return [
      { name: clean(numbered[0].nom),  etapeIndex: 0,  icon: 'icon_bauxite.svg',            count: window.SVAUtils.countEntreprisesInEtape(numbered[0]).unique },
      { name: clean(numbered[1].nom),  etapeIndex: 1,  icon: 'icon_raffinage.svg',           count: window.SVAUtils.countEntreprisesInEtape(numbered[1]).unique },
      { name: clean(numbered[2].nom),  etapeIndex: 2,  icon: 'icon_fusion.svg',              count: window.SVAUtils.countEntreprisesInEtape(numbered[2]).unique },
      { name: clean(numbered[3].nom),  etapeIndex: 3,  icon: 'icon_moulage_alliage.svg',     count: window.SVAUtils.countEntreprisesInEtape(numbered[3]).unique },
      { name: 'Transformation intermédiaire', etapeIndex: 5, icon: 'icon_transformation_int.svg', count: mergeCount([4, 5]) },
      { name: 'Fabrication (pièces)',          etapeIndex: 7, icon: 'icon_fabrication.svg',        count: mergeCount([6, 7]) },
      { name: clean(numbered[8].nom),  etapeIndex: 8,  icon: 'icon_distribution.svg',        count: window.SVAUtils.countEntreprisesInEtape(numbered[8]).unique },
      { name: clean(numbered[9].nom),  etapeIndex: 9,  icon: 'icon_recyclage.svg',           count: window.SVAUtils.countEntreprisesInEtape(numbered[9]).unique },
      { name: clean(numbered[10].nom), etapeIndex: 10, icon: 'icon_soutien_ecosystem.svg',   count: window.SVAUtils.countEntreprisesInEtape(numbered[10]).unique },
    ];
  }, [numbered]);

  // Arc elliptique natif SVG — vraiment round, sans aucune jonction bezier
  const pathD = useMemo(() => {
    const p0 = ovalPoint(0);
    const p8 = ovalPoint(OV.n - 1);
    // A rx ry x-rotation large-arc-flag(1=arc>180°) sweep-flag(1=sens horaire SVG) x y
    return `M ${p0.x.toFixed(2)} ${p0.y.toFixed(2)} A ${OV.rx} ${OV.ry} 0 1 1 ${p8.x.toFixed(2)} ${p8.y.toFixed(2)}`;
  }, []);

  useEffect(() => {
    let cancelled = false;
    const ids = [];
    for (let i = 0; i <= displayNodes.length + 1; i++) {
      ids.push(setTimeout(() => { if (!cancelled) setRevealedCount(i); }, 200 + i * 110));
    }
    return () => { cancelled = true; ids.forEach(clearTimeout); };
  }, []);

  const pathRef = useRef(null);
  const [pathLen, setPathLen] = useState(0);
  useEffect(() => {
    if (pathRef.current) setPathLen(pathRef.current.getTotalLength());
  }, [pathD]);

  const header = (
    <header className="er-head">
      <div>
        <div className="er-head__eyebrow">Vallée de l'aluminium</div>
        <h1 className="er-head__title">Le <em>circuit</em> de l'<span className="silver">aluminium</span></h1>
      </div>
      <div className="er-head__count">
        <div className="er-head__count-top">
          <div className="num">{floorTen(totalEntreprises)}<sup>+</sup></div>
          <div className="lbl">entreprises<br />référencées</div>
        </div>
        <button className="chip chip--all er-head__all-btn" onClick={() => setShowAllPanel(true)}>
          <span className="chip__lbl">Voir toutes les entreprises</span>
          <span className="chip__count">{totalEntreprises}</span>
        </button>
      </div>
    </header>
  );

  return (
    <div className="er-screen">
      <div className="er-bg">
        <div className="er-bg__blob b1" />
        <div className="er-bg__blob b2" />
        <div className="er-bg__blob b3" />
      </div>

      {/* ── Desktop ── */}
      {header}

      <div className="er-stage er-desktop-only">
        <svg className="er-svg" viewBox="0 0 1000 600" preserveAspectRatio="none" aria-hidden="true">
          <defs>
            <filter id="riverGlow">
              <feGaussianBlur stdDeviation="2" result="blur" />
              <feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
            </filter>
            <path id="riverPath" d={pathD} />
          </defs>
          <path d={pathD} fill="none" style={{ stroke: 'var(--neutral-400)' }} strokeWidth="1.5" strokeDasharray="3 7" vectorEffect="non-scaling-stroke" />
          <path ref={pathRef} d={pathD} fill="none" stroke="none" />
          {pathLen > 0 && [0, 1, 2, 3, 4, 5].map(i => (
            <circle key={i} r={i % 2 === 0 ? 4 : 3} fill="#4d7bd6" filter="url(#riverGlow)" opacity={0.85}>
              <animateMotion dur={`${10 + i * 1.6}s`} begin={`${-i * 1.8}s`} repeatCount="indefinite" rotate="auto">
                <mpath xlinkHref="#riverPath" />
              </animateMotion>
              <animate attributeName="opacity" values="0;0.85;0.85;0" dur={`${10 + i * 1.6}s`} begin={`${-i * 1.8}s`} repeatCount="indefinite" />
            </circle>
          ))}
        </svg>

        {displayNodes.map((node, i) => {
          const pos = positions[i];
          if (!pos) return null;
          const visible = i < revealedCount;
          return (
            <button
              key={node.etapeIndex}
              className="er-node"
              onClick={() => onPickEtape(node.etapeIndex)}
              style={{
                left: `${pos.x * 100}%`,
                top: `${pos.y * 100}%`,
                opacity: visible ? 1 : 0,
                transform: `translate(-50%, -50%) scale(${visible ? 1 : 0.5})`,
                transition: 'opacity 540ms cubic-bezier(0.34,1.56,0.64,1), transform 540ms cubic-bezier(0.34,1.56,0.64,1)',
              }}
            >
              <div className="er-node__ring" aria-hidden="true" />
              <div className="er-node__dot">
                <img className="er-node__icon" src={RIVER_ICON_BASE + node.icon} alt="" aria-hidden="true" />
              </div>
              <div className="er-node__label">
                <div className="er-node__name">{node.name}</div>
                <div className={`er-node__count ${node.count === 0 ? 'empty' : ''}`}>
                  {node.count === 0 ? 'aucune entreprise' : node.count === 1 ? '1 entreprise' : `${node.count} entreprises`}
                </div>
              </div>
            </button>
          );
        })}

        <button
          className="er-center-btn"
          onClick={() => onPickTransversal(0)}
          style={{
            left: `${(OV.cx / 1000 * 100).toFixed(1)}%`,
            top: `${(OV.cy / 600 * 100).toFixed(1)}%`,
            opacity: revealedCount > displayNodes.length ? 1 : 0,
            transform: `translate(-50%, -50%) scale(${revealedCount > displayNodes.length ? 1 : 0.8})`,
            transition: 'opacity 540ms cubic-bezier(0.34,1.56,0.64,1), transform 540ms cubic-bezier(0.34,1.56,0.64,1)',
          }}
        >
          <div className="er-center-btn__icon">
            <img src={RIVER_ICON_BASE + 'icon_equipementiers.svg'} alt="" aria-hidden="true" />
          </div>
          <span className="er-center-btn__name">Équipementiers et services</span>
        </button>
      </div>

      <footer className="er-footer er-desktop-only">
        <div className="er-footer__text">Région du Saguenay–Lac-St-Jean</div>
      </footer>

      {/* ── Mobile list ── */}
      <div className="er-mobile">
        <div className="er-mobile__track">
          {displayNodes.map((node, i) => (
            <button
              key={node.etapeIndex}
              className="er-mobile__item"
              onClick={() => onPickEtape(node.etapeIndex)}
            >
              <div className="er-mobile__dot">
                <img src={RIVER_ICON_BASE + node.icon} alt="" aria-hidden="true" width="48" height="48" />
              </div>
              <div className="er-mobile__info">
                <div className="er-mobile__name">{node.name}</div>
                <div className={`er-mobile__count ${node.count === 0 ? 'empty' : ''}`}>
                  {node.count === 0 ? 'Aucune entreprise' : node.count === 1 ? '1 entreprise' : `${node.count} entreprises`}
                </div>
              </div>
            </button>
          ))}
        </div>

        <button className="er-mobile__transv" onClick={() => onPickTransversal(0)}>
          <div className="er-mobile__dot">
            <img src={RIVER_ICON_BASE + 'icon_equipementiers.svg'} alt="" aria-hidden="true" width="48" height="48" />
          </div>
          <div className="er-mobile__info">
            <div className="er-mobile__name">Équipementiers et services</div>
          </div>
        </button>
      </div>

      {showAllPanel && (
        <AllCompaniesPanel
          entreprises={allEntreprises}
          onClose={() => setShowAllPanel(false)}
          onPick={(ent) => { setShowAllPanel(false); onPickEntreprise(ent); }}
        />
      )}
    </div>
  );
}

function CircuitScreen({ data, onPickEtape, onPickTransversal, onPickEntreprise }) {
  const numbered = data.etapes.slice(0, 11);
  const { allEntreprises, totalEntreprises } = React.useMemo(() => {
    const seen = new Set();
    const all = [];
    data.etapes.forEach(e => e.categories.forEach(c => c.services.forEach(s => s.entreprises.forEach(ent => {
      if (!seen.has(ent.nom)) { seen.add(ent.nom); all.push(ent); }
    }))));
    return { allEntreprises: all, totalEntreprises: seen.size };
  }, [data]);
  return (
    <CircuitLayout
      numbered={numbered}
      allEntreprises={allEntreprises}
      totalEntreprises={totalEntreprises}
      onPickEtape={onPickEtape}
      onPickTransversal={onPickTransversal}
      onPickEntreprise={onPickEntreprise}
    />
  );
}

window.CircuitScreen = CircuitScreen;
