// diagram.jsx — radial concept diagram for the Policy Lab.
// Phases are rendered as a connected ring of 4 curved arc segments around the centre.

const { useState, useMemo } = React;

// ----- Geometry -------------------------------------------------------------
const CX = 400, CY = 400;

// Inner: the phase ring of thin joined arc segments
const R_RING_INNER   = 112;  // phase arc band inner edge
const R_RING_OUTER   = 165;  // phase arc band outer edge
const R_LABEL        = 177;  // phase labels (hugging just outside the band)

// Context rings (concentric tints, behind the phase ring)
const R_PROJECT      = 218;  // Project boundary
const R_INVOLVED     = 308;  // Involved actors boundary
const R_SOCIETY      = 392;  // Politics & society boundary (also Policy Lab boundary)

// Arc band gap
const GAP_DEG = 0; // segments join edge-to-edge (separated only by the white stroke)

const polar = (angleDeg, r) => {
  const a = (angleDeg - 90) * Math.PI / 180;
  return { x: CX + r * Math.cos(a), y: CY + r * Math.sin(a) };
};

// Phase quadrants: centered on top / right / bottom / left.
// Each spans 90deg minus the gap.
const PHASE_ARCS = {
  co_design:      { center:   0 },
  co_production:  { center:  90 },
  co_evaluation:  { center: 180 },
  co_integration: { center: 270 },
};

function arcBandPath(centerAngle, span, rIn, rOut) {
  const a1 = centerAngle - span / 2;
  const a2 = centerAngle + span / 2;
  const p1 = polar(a1, rIn);
  const p2 = polar(a2, rIn);
  const p3 = polar(a2, rOut);
  const p4 = polar(a1, rOut);
  return `M ${p1.x} ${p1.y}
          A ${rIn} ${rIn} 0 0 1 ${p2.x} ${p2.y}
          L ${p3.x} ${p3.y}
          A ${rOut} ${rOut} 0 0 0 ${p4.x} ${p4.y} Z`;
}

// Actor positions are no longer rendered on the diagram — actors surface
// via hover tooltips on each context ring instead.


// Label anchor based on x position
function anchorFor(x) {
  if (x > CX + 18) return "start";
  if (x < CX - 18) return "end";
  return "middle";
}

// ----- Main component -------------------------------------------------------

function ConceptDiagram({ selectedPhase, onSelectPhase, hoveredRing, onHoverRing, dimMethods = false }) {
  const phases = window.PHASES;

  // Donut hit-area path for a ring band (full 360°).
  // Uses two arcs to draw a closed annular shape.
  const donut = (rIn, rOut) => {
    const top1 = polar(0,   rIn);
    const bot1 = polar(180, rIn);
    const top2 = polar(0,   rOut);
    const bot2 = polar(180, rOut);
    return [
      `M ${top2.x} ${top2.y}`,
      `A ${rOut} ${rOut} 0 1 1 ${bot2.x} ${bot2.y}`,
      `A ${rOut} ${rOut} 0 1 1 ${top2.x} ${top2.y}`,
      `Z`,
      `M ${top1.x} ${top1.y}`,
      `A ${rIn} ${rIn} 0 1 0 ${bot1.x} ${bot1.y}`,
      `A ${rIn} ${rIn} 0 1 0 ${top1.x} ${top1.y}`,
      `Z`,
    ].join(" ");
  };

  const ringHovered = (id) => hoveredRing === id;
  const setHover = (id) => onHoverRing && onHoverRing(id);

  // Dashed hexagon — sized so the outer "Politics & society" ring bulges
  // partially outside it (vertices sit just outside the ring, edges cut inside).
  const hexPath = useMemo(() => {
    const r = R_SOCIETY + 16; // vertices just outside the ring; edge midpoints cut inside it
    const pts = [0, 60, 120, 180, 240, 300].map(deg => polar(deg, r));
    return "M " + pts.map(p => `${p.x.toFixed(1)} ${p.y.toFixed(1)}`).join(" L ") + " Z";
  }, []);

  return (
    <svg viewBox="-100 -100 1000 1000" className="concept-svg" role="img" aria-label="Policy Lab concept diagram">
      <defs>
        <radialGradient id="paperGlow" cx="50%" cy="50%" r="55%">
          <stop offset="0%"  stopColor="#FFFFFF" stopOpacity="0.7" />
          <stop offset="60%" stopColor="#F5F3EE" stopOpacity="0" />
        </radialGradient>
        <marker id="loopHead" markerWidth="9" markerHeight="9" refX="6.5" refY="4.5"
                orient="auto" markerUnits="userSpaceOnUse">
          <path d="M0 0 L9 4.5 L0 9 Z" fill="#356259" />
        </marker>
      </defs>

      {/* Context rings (filled, low opacity, stacked) */}
      <circle cx={CX} cy={CY} r={R_SOCIETY}  fill="#356259"
              fillOpacity={ringHovered("society")  ? 0.10 : 0.05}
              stroke="#356259"
              strokeOpacity={ringHovered("society")  ? 0.45 : 0.18} />
      <circle cx={CX} cy={CY} r={R_INVOLVED} fill="#356259"
              fillOpacity={ringHovered("involved") ? 0.14 : 0.07}
              stroke="#356259"
              strokeOpacity={ringHovered("involved") ? 0.50 : 0.22} />
      <circle cx={CX} cy={CY} r={R_PROJECT}  fill="#356259"
              fillOpacity={ringHovered("project")  ? 0.18 : 0.10}
              stroke="#356259"
              strokeOpacity={ringHovered("project")  ? 0.55 : 0.30} />

      {/* Soft warm glow at very centre */}
      <circle cx={CX} cy={CY} r={R_PROJECT - 6} fill="url(#paperGlow)" />

      {/* Policy Lab dashed hexagon perimeter */}
      <path d={hexPath} fill="none"
            stroke="#356259" strokeOpacity="0.45" strokeWidth="1.2"
            strokeDasharray="4 6" strokeLinejoin="round" />
      {(() => {
        const llp = polar(318, R_SOCIETY + 40);
        return (
          <text x={llp.x} y={llp.y} fontSize="13" fill="#356259" fontStyle="italic"
                textAnchor="start" style={{ letterSpacing: "0.08em" }}>Policy Lab</text>
        );
      })()}

      {/* Phase ring — 4 joined arc segments */}
      {phases.map(p => {
        const arc = PHASE_ARCS[p.id];
        const span = 90 - GAP_DEG;
        const d = arcBandPath(arc.center, span, R_RING_INNER, R_RING_OUTER);
        const dHighlight = arcBandPath(arc.center, span - 5, R_RING_INNER + 2, R_RING_INNER + 18);
        const selected = selectedPhase === p.id;
        const dimmed = dimMethods && selectedPhase && !selected;
        const labelPos = polar(arc.center, R_LABEL);
        const anchor = anchorFor(labelPos.x);
        return (
          <g key={p.id}
             className={"phase-arc" + (selected ? " is-selected" : "") + (dimmed ? " is-dim" : "")}
             onClick={() => onSelectPhase && onSelectPhase(p.id)}
             style={{ cursor: "pointer" }}>
            <path d={d}
                  fill={p.color}
                  stroke="#FFFFFF" strokeWidth="2"
                  opacity={dimmed ? 0.35 : 1}
                  className="phase-arc-fill" />
            <path d={dHighlight}
                  fill="rgba(255,255,255,0.22)"
                  opacity={dimmed ? 0.4 : 1}
                  style={{ pointerEvents: "none" }} />
            {selected && (
              <path d={arcBandPath(arc.center, 90 - GAP_DEG, R_RING_INNER - 5, R_RING_OUTER + 5)}
                    fill="none" stroke={p.color} strokeOpacity="0.5" strokeWidth="2.5" />
            )}
            <text x={labelPos.x} y={labelPos.y + 5}
                  textAnchor={anchor} fontSize="16"
                  fontFamily="'DM Serif Display', serif"
                  fill={selected ? p.color : "#465555"}
                  opacity={dimmed ? 0.5 : 1}>{p.label}</text>
          </g>
        );
      })}

      {/* Feedback loop: Co-Evaluation can flow back into Co-Production */}
      {(() => {
        const start = polar(168, 96);  // leaves the Co-Evaluation arc (bottom)
        const end   = polar(112, 96);  // arrives at the Co-Production arc (right)
        const ctrl  = polar(140, 46);  // bow toward the centre
        const loopD = `M ${start.x.toFixed(1)} ${start.y.toFixed(1)} Q ${ctrl.x.toFixed(1)} ${ctrl.y.toFixed(1)} ${end.x.toFixed(1)} ${end.y.toFixed(1)}`;

        // Concentric inner copy of the loop — the "iterate" label rides this so it
        // curves alongside the dashed line instead of crossing it.
        const lStart = polar(168, 77);
        const lEnd   = polar(112, 77);
        const lCtrl  = polar(140, 37);
        const labelD = `M ${lStart.x.toFixed(1)} ${lStart.y.toFixed(1)} Q ${lCtrl.x.toFixed(1)} ${lCtrl.y.toFixed(1)} ${lEnd.x.toFixed(1)} ${lEnd.y.toFixed(1)}`;

        return (
          <g className="feedback-loop" style={{ pointerEvents: "none" }}>
            <path id="iterateArc" d={labelD} fill="none" stroke="none" />
            <path d={loopD} fill="none" stroke="#356259" strokeOpacity="0.75"
                  strokeWidth="2" strokeDasharray="5 4" markerEnd="url(#loopHead)" />
            <text textAnchor="middle" fontSize="9.5"
                  fill="#356259" fontStyle="italic"
                  style={{ letterSpacing: "0.12em", textTransform: "uppercase" }}>
              <textPath href="#iterateArc" startOffset="50%">iterate</textPath>
            </text>
          </g>
        );
      })()}

      {/* Centre is left open */}

      {/* Actor markers removed — actors surface through hover tooltips on each context ring */}

      {/* Ring hover hit-areas (drawn last so they sit on top of the rings
          but BELOW the phase ring, which we redraw above via z-order of children).
          We render hit areas at the end with pointer-events: all, fill transparent. */}
      <g className="ring-hits">
        {/* Project ring band: between phase outer edge and project boundary */}
        <path d={donut(R_RING_OUTER + 4, R_PROJECT)}
              fill="#FFFFFF" fillOpacity="0" fillRule="evenodd"
              onMouseEnter={() => setHover("project")}
              onMouseLeave={() => setHover(null)}
              style={{ cursor: "help" }} />
        {/* Involved actors band */}
        <path d={donut(R_PROJECT + 1, R_INVOLVED)}
              fill="#FFFFFF" fillOpacity="0" fillRule="evenodd"
              onMouseEnter={() => setHover("involved")}
              onMouseLeave={() => setHover(null)}
              style={{ cursor: "help" }} />
        {/* Politics & society band */}
        <path d={donut(R_INVOLVED + 1, R_SOCIETY)}
              fill="#FFFFFF" fillOpacity="0" fillRule="evenodd"
              onMouseEnter={() => setHover("society")}
              onMouseLeave={() => setHover(null)}
              style={{ cursor: "help" }} />
      </g>

      {/* Context ring labels — small uppercase, set along the lower-left spoke
          so they clear the phase labels sitting on the cardinal axes */}
      {(() => {
        const LABEL_ANGLE = 214; // between the bottom and left phase axes (clear gap)
        const rings = [
          { id: "society",  r: R_SOCIETY,  text: "Politics & society" },
          { id: "involved", r: R_INVOLVED, text: "Involved actors" },
          { id: "project",  r: R_PROJECT,  text: "Project" },
        ];
        return (
          <g fontSize="10.5" fill="#465555"
             style={{ letterSpacing: "0.14em", textTransform: "uppercase", pointerEvents: "none" }}>
            {rings.map(({ id, r, text }) => {
              const pos = polar(LABEL_ANGLE, r - 13);
              return (
                <text key={id} x={pos.x.toFixed(1)} y={pos.y.toFixed(1)} textAnchor="end"
                      opacity={ringHovered(id) ? 1 : 0.7}
                      fontWeight={ringHovered(id) ? 600 : 400}>{text}</text>
              );
            })}
          </g>
        );
      })()}
    </svg>
  );
}

window.ConceptDiagram = ConceptDiagram;
