// year-wheel.jsx — the central circular wheel

const SEASON_LABELS = {
  spring: { da: 'Forår',         icon: 'spring' },
  summer: { da: 'Sommer',        icon: 'summer' },
  autumn: { da: 'Efterår',       icon: 'autumn' },
  winter: { da: 'Vinter',        icon: 'winter' },
};

// Convert (cx, cy, radius, angleDeg) → point. 0° = top (12 o'clock), clockwise.
function polar(cx, cy, r, angleDeg) {
  const rad = ((angleDeg - 90) * Math.PI) / 180;
  return [cx + r * Math.cos(rad), cy + r * Math.sin(rad)];
}

// SVG path for an annular sector (donut slice)
function annularSectorPath(cx, cy, rOuter, rInner, startDeg, endDeg) {
  const [x1, y1] = polar(cx, cy, rOuter, startDeg);
  const [x2, y2] = polar(cx, cy, rOuter, endDeg);
  const [x3, y3] = polar(cx, cy, rInner, endDeg);
  const [x4, y4] = polar(cx, cy, rInner, startDeg);
  const largeArc = endDeg - startDeg > 180 ? 1 : 0;
  return [
    `M ${x1} ${y1}`,
    `A ${rOuter} ${rOuter} 0 ${largeArc} 1 ${x2} ${y2}`,
    `L ${x3} ${y3}`,
    `A ${rInner} ${rInner} 0 ${largeArc} 0 ${x4} ${y4}`,
    'Z',
  ].join(' ');
}

// A trip-band on the wheel: arc from trip.start to trip.end at a fixed radius
function tripArcPath(cx, cy, r, trip) {
  const a1 = window.isoToWheelAngle(trip.start);
  const a2 = window.isoToWheelAngle(trip.end);
  const [x1, y1] = polar(cx, cy, r, a1);
  const [x2, y2] = polar(cx, cy, r, a2);
  const largeArc = a2 - a1 > 180 ? 1 : 0;
  return `M ${x1} ${y1} A ${r} ${r} 0 ${largeArc} 1 ${x2} ${y2}`;
}

// Tiny inline season glyphs
function SeasonGlyph({ kind, size = 18, color = 'currentColor' }) {
  const props = { width: size, height: size, fill: 'none', stroke: color,
                  strokeWidth: 1.2, strokeLinecap: 'round', strokeLinejoin: 'round' };
  if (kind === 'spring') return (
    <svg viewBox="0 0 24 24" {...props}>
      <path d="M12 20 V10" />
      <path d="M12 14 C 9 12 7 8 9 6 C 11 7 12 10 12 14" fill={color} fillOpacity=".15"/>
      <path d="M12 13 C 15 11 17 8 15 6 C 13 7 12 9 12 13" fill={color} fillOpacity=".15"/>
      <circle cx="12" cy="6" r="1.4" fill={color}/>
    </svg>
  );
  if (kind === 'summer') return (
    <svg viewBox="0 0 24 24" {...props}>
      <circle cx="12" cy="12" r="3.5" fill={color} fillOpacity=".15"/>
      {[0,45,90,135,180,225,270,315].map((a) => {
        const rad = (a * Math.PI)/180;
        const x1 = 12 + Math.cos(rad) * 6, y1 = 12 + Math.sin(rad) * 6;
        const x2 = 12 + Math.cos(rad) * 9, y2 = 12 + Math.sin(rad) * 9;
        return <line key={a} x1={x1} y1={y1} x2={x2} y2={y2}/>;
      })}
    </svg>
  );
  if (kind === 'autumn') return (
    <svg viewBox="0 0 24 24" {...props}>
      <path d="M12 4 C 7 8 6 14 8 19 C 11 17 14 14 16 9 C 15 6 13 4 12 4 Z" fill={color} fillOpacity=".15"/>
      <path d="M12 4 V 19" />
      <path d="M12 9 L 9 11" /><path d="M12 12 L 14.5 10.5" />
      <path d="M12 15 L 9.5 16.5" />
    </svg>
  );
  if (kind === 'winter') return (
    <svg viewBox="0 0 24 24" {...props}>
      <line x1="12" y1="3" x2="12" y2="21"/>
      <line x1="4" y1="7.5" x2="20" y2="16.5"/>
      <line x1="4" y1="16.5" x2="20" y2="7.5"/>
    </svg>
  );
  return null;
}

// MAIN COMPONENT
function useTick(intervalMs = 1000) {
  const [, setT] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setT((x) => x + 1), intervalMs);
    return () => clearInterval(id);
  }, [intervalMs]);
}

function YearWheel({ trips, today, selectedId, onSelect, variant = 'natural', liveNow }) {
  useTick(1000);
  const SIZE = 720;
  const CX = SIZE / 2, CY = SIZE / 2;

  // Radii (outer → inner)
  const R_OUTER       = 340;        // outer ring (months)
  const R_MONTHS_IN   = 308;
  const R_QUADRANT_OUT= 296;        // quadrant fills
  const R_QUADRANT_IN = 156;
  const R_TRIP_BAND   = 245;        // trip arc + label
  const R_TICK_OUT    = 308;
  const R_TICK_IN     = 296;
  const R_INNER       = 144;        // inner core
  const R_HUB         = 56;

  const todayAngle = window.dateToAngle(today);
  const todayDate  = new Date(today);

  // Find next upcoming trip (or current trip)
  const upcoming = trips
    .map((t) => ({ ...t, daysUntil: window.daysBetween(today, t.start) }))
    .find((t) => t.daysUntil >= -3) || trips[0];

  // ── Quadrant colors per season (natural Asserbo palette) ────────────────
  const QUAD_FILLS = {
    natural: {
      spring: 'url(#grad-spring)',
      summer: 'url(#grad-summer)',
      autumn: 'url(#grad-autumn)',
      winter: 'url(#grad-winter)',
    },
    parchment: {
      spring: '#e8dcc4', summer: '#dcc89a',
      autumn: '#c9a14a', winter: '#8a7858',
    },
    monochrome: {
      spring: '#3a342a', summer: '#2e2920',
      autumn: '#241f18', winter: '#1a1610',
    },
  };

  const fills = QUAD_FILLS[variant] || QUAD_FILLS.natural;

  // Month tick positions (12 months, 30° apart)
  const monthTicks = Array.from({ length: 12 }, (_, i) => {
    const angle = (i / 12) * 360;
    return { angle, name: window.MONTHS_SHORT_DA[i].toUpperCase() };
  });

  return (
    <svg viewBox={`0 0 ${SIZE} ${SIZE}`} className="year-wheel" xmlns="http://www.w3.org/2000/svg">
      <defs>
        {/* Quadrant gradients — soft naturals */}
        <radialGradient id="grad-spring" cx="50%" cy="50%" r="65%">
          <stop offset="0%" stopColor="#7a8a5c"/><stop offset="100%" stopColor="#5a6a3e"/>
        </radialGradient>
        <radialGradient id="grad-summer" cx="50%" cy="50%" r="65%">
          <stop offset="0%" stopColor="#a8804e"/><stop offset="100%" stopColor="#7a5a32"/>
        </radialGradient>
        <radialGradient id="grad-autumn" cx="50%" cy="50%" r="65%">
          <stop offset="0%" stopColor="#8a3e2a"/><stop offset="100%" stopColor="#5a2a18"/>
        </radialGradient>
        <radialGradient id="grad-winter" cx="50%" cy="50%" r="65%">
          <stop offset="0%" stopColor="#3a4258"/><stop offset="100%" stopColor="#1f2532"/>
        </radialGradient>

        {/* Subtle paper-grain overlay */}
        <pattern id="grain" x="0" y="0" width="180" height="180" patternUnits="userSpaceOnUse">
          <rect width="180" height="180" fill="rgba(255,255,255,0)"/>
          <circle cx="20"  cy="40"  r=".5" fill="rgba(255,255,255,.05)"/>
          <circle cx="80"  cy="120" r=".5" fill="rgba(0,0,0,.06)"/>
          <circle cx="140" cy="60"  r=".5" fill="rgba(255,255,255,.05)"/>
          <circle cx="60"  cy="160" r=".5" fill="rgba(0,0,0,.06)"/>
          <circle cx="160" cy="20"  r=".5" fill="rgba(255,255,255,.04)"/>
        </pattern>

        {/* Inner soft glow */}
        <radialGradient id="hub-glow" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="#f5ecd6" stopOpacity=".95"/>
          <stop offset="60%" stopColor="#e8dcc4" stopOpacity=".5"/>
          <stop offset="100%" stopColor="#c9a14a" stopOpacity="0"/>
        </radialGradient>

        {/* Ring stroke */}
        <linearGradient id="ringStroke" x1="0%" y1="0%" x2="100%" y2="100%">
          <stop offset="0%" stopColor="#c9a14a"/>
          <stop offset="100%" stopColor="#8a7858"/>
        </linearGradient>

        {/* Path for curved month labels */}
        <path id="month-label-path"
              d={`M ${CX - (R_OUTER - 16)} ${CY} A ${R_OUTER - 16} ${R_OUTER - 16} 0 1 1 ${CX + (R_OUTER - 16)} ${CY} A ${R_OUTER - 16} ${R_OUTER - 16} 0 1 1 ${CX - (R_OUTER - 16)} ${CY}`}/>
      </defs>

      {/* Outer ring backdrop */}
      <circle cx={CX} cy={CY} r={R_OUTER} fill="#1a1410" stroke="url(#ringStroke)" strokeWidth="1"/>

      {/* 4 quadrants */}
      {trips.map((trip) => {
        const fill = fills[trip.season];
        const isHighlighted = selectedId === trip.id || (!selectedId && upcoming.id === trip.id);
        return (
          <g key={trip.id} className={`quadrant quadrant-${trip.season}`}
             onClick={() => onSelect(trip.id)} style={{ cursor: 'pointer' }}>
            <path d={annularSectorPath(CX, CY, R_QUADRANT_OUT, R_QUADRANT_IN, trip.angle.from, trip.angle.to)}
                  fill={fill} opacity={isHighlighted ? 1 : 0.78}
                  className="quadrant-fill"/>
            <path d={annularSectorPath(CX, CY, R_QUADRANT_OUT, R_QUADRANT_IN, trip.angle.from, trip.angle.to)}
                  fill="url(#grain)" pointerEvents="none"/>
          </g>
        );
      })}

      {/* Quadrant divider lines */}
      {[0, 90, 180, 270].map((a) => {
        const [x1, y1] = polar(CX, CY, R_QUADRANT_IN, a);
        const [x2, y2] = polar(CX, CY, R_QUADRANT_OUT, a);
        return <line key={a} x1={x1} y1={y1} x2={x2} y2={y2}
                     stroke="rgba(244,239,230,.18)" strokeWidth="0.5"/>;
      })}

      {/* Month ticks (just inside outer ring) */}
      {monthTicks.map(({ angle, name }, i) => {
        const [x1, y1] = polar(CX, CY, R_TICK_IN, angle);
        const [x2, y2] = polar(CX, CY, R_TICK_OUT, angle);
        return (
          <g key={i}>
            <line x1={x1} y1={y1} x2={x2} y2={y2}
                  stroke="#c9a14a" strokeWidth="0.6" opacity=".7"/>
          </g>
        );
      })}

      {/* Month labels — placed at midpoint of each month */}
      {monthTicks.map(({ name }, i) => {
        const angle = (i / 12) * 360 + 15; // midpoint
        const [x, y] = polar(CX, CY, R_OUTER - 16, angle);
        return (
          <text key={i} x={x} y={y}
                fill="rgba(244,239,230,.6)"
                fontSize="9"
                fontFamily="var(--font-mono)"
                letterSpacing="0.18em"
                textAnchor="middle"
                dominantBaseline="middle"
                transform={`rotate(${angle} ${x} ${y})`}>
            {name}
          </text>
        );
      })}

      {/* Trip arcs + labels */}
      {trips.map((trip) => {
        const a1 = window.isoToWheelAngle(trip.start);
        const a2 = window.isoToWheelAngle(trip.end);
        const midAngle = (a1 + a2) / 2;
        const [lx, ly] = polar(CX, CY, R_TRIP_BAND - 10, midAngle);
        const isUpcoming = upcoming.id === trip.id;
        return (
          <g key={trip.id}>
            {/* Trip arc */}
            <path d={tripArcPath(CX, CY, R_TRIP_BAND, trip)}
                  fill="none"
                  stroke="#f5ecd6"
                  strokeWidth={isUpcoming ? 5 : 3}
                  strokeLinecap="round"
                  opacity={isUpcoming ? 1 : 0.6}/>
            {/* Outer marker dot at start of trip */}
            {(() => {
              const [px, py] = polar(CX, CY, R_TRIP_BAND, a1);
              return <circle cx={px} cy={py} r="3" fill="#c9a14a" stroke="#1a1410" strokeWidth="0.5"/>;
            })()}
            {/* Quadrant label inside — midpoint of the season's angular span */}
            <g transform={`translate(${polar(CX, CY, R_QUADRANT_IN + 70, (trip.angle.from + trip.angle.to) / 2).join(' ')})`}>
              <g transform="translate(-12, -34)">
                <SeasonGlyph kind={trip.season} size={24} color="#f5ecd6"/>
              </g>
              <text fill="#f5ecd6" fontSize="13" fontFamily="var(--font-serif)"
                    fontStyle="italic" textAnchor="middle" y="-2"
                    letterSpacing="0.04em">
                {trip.name.replace('-turen', '').replace('turen', '')}
              </text>
              <text fill="rgba(245,236,214,.6)" fontSize="8.5" fontFamily="var(--font-mono)"
                    textAnchor="middle" y="13" letterSpacing="0.18em">
                {window.fmtDateRange(trip.start, trip.end).toUpperCase()}
              </text>
            </g>
          </g>
        );
      })}

      {/* Today indicator — a thin rotating brass needle from hub to outer ring */}
      {(() => {
        const [tx, ty] = polar(CX, CY, R_QUADRANT_OUT - 4, todayAngle);
        const [hx, hy] = polar(CX, CY, R_HUB + 6, todayAngle);
        return (
          <g className="today-needle">
            <line x1={hx} y1={hy} x2={tx} y2={ty}
                  stroke="#f5ecd6" strokeWidth="1.5" strokeLinecap="round"
                  opacity=".95"/>
            <circle cx={tx} cy={ty} r="4" fill="#f5ecd6" stroke="#c9a14a" strokeWidth="1"/>
            <circle cx={tx} cy={ty} r="8" fill="none" stroke="#f5ecd6"
                    strokeWidth="0.5" opacity=".4">
              <animate attributeName="r" values="6;12;6" dur="3s" repeatCount="indefinite"/>
              <animate attributeName="opacity" values=".5;0;.5" dur="3s" repeatCount="indefinite"/>
            </circle>
          </g>
        );
      })()}

      {/* Inner core */}
      <circle cx={CX} cy={CY} r={R_INNER} fill="#1a1410"/>
      <circle cx={CX} cy={CY} r={R_INNER} fill="url(#hub-glow)" opacity=".4"/>
      <circle cx={CX} cy={CY} r={R_INNER} fill="none"
              stroke="url(#ringStroke)" strokeWidth="0.5"/>

      {/* Center text — live ticking countdown to next trip */}
      {(() => {
        const now = liveNow || new Date();
        const target = new Date(upcoming.start + 'T16:00:00'); // arrive afternoon
        const diff = Math.max(0, target - now);
        const SEC = 1000, MIN = 60*SEC, HR = 60*MIN, DAY = 24*HR;
        const days  = Math.floor(diff / DAY);
        const hours = Math.floor((diff % DAY) / HR);
        const mins  = Math.floor((diff % HR) / MIN);
        const secs  = Math.floor((diff % MIN) / SEC);
        const pad = (n) => String(n).padStart(2, '0');
        return (
          <g className="hub-text" textAnchor="middle">
            <text x={CX} y={CY - 56} fill="rgba(245,236,214,.45)"
                  fontSize="8.5" fontFamily="var(--font-mono)" letterSpacing="0.32em">
              NÆSTE INDKALDELSE
            </text>
            <text x={CX} y={CY - 36} fill="#f5ecd6"
                  fontSize="18" fontFamily="var(--font-serif)" fontStyle="italic"
                  letterSpacing="0.01em">
              {upcoming.name}
            </text>

            {/* Days — large brass numeral */}
            <text x={CX} y={CY + 8} fill="#c9a14a"
                  fontSize="58" fontFamily="var(--font-serif)" fontWeight="500"
                  letterSpacing="-0.03em" dominantBaseline="middle">
              {days}
            </text>
            <text x={CX} y={CY + 36} fill="rgba(245,236,214,.55)"
                  fontSize="9" fontFamily="var(--font-mono)" letterSpacing="0.32em">
              DAGE
            </text>

            {/* HH : MM : SS — ticking */}
            <g transform={`translate(${CX} ${CY + 64})`}>
              <text fill="#f5ecd6" fontSize="14" fontFamily="var(--font-mono)"
                    letterSpacing="0.08em" textAnchor="middle"
                    style={{ fontVariantNumeric: 'tabular-nums' }}>
                {pad(hours)}<tspan fill="rgba(201,161,74,.7)">:</tspan>{pad(mins)}<tspan fill="rgba(201,161,74,.7)">:</tspan>{pad(secs)}
              </text>
              <text y="14" fill="rgba(245,236,214,.35)" fontSize="7"
                    fontFamily="var(--font-mono)" letterSpacing="0.32em" textAnchor="middle">
                T &nbsp;&nbsp; M &nbsp;&nbsp; S
              </text>
            </g>

            <text x={CX} y={CY + 96} fill="rgba(245,236,214,.4)"
                  fontSize="8.5" fontFamily="var(--font-mono)" letterSpacing="0.18em">
              {window.fmtDate(upcoming.start).toUpperCase()}
            </text>
          </g>
        );
      })()}
    </svg>
  );
}

Object.assign(window, { YearWheel, SeasonGlyph });
