// cop-elements.jsx — visual building blocks for the COP explainer video.
// Depends on globals from video-shared.jsx: W, H, VC, lerp, smooth, ramp, fadeWindow.

// ── Outdoor air-to-water heat pump unit ────────────────────────────────────
// Stylised: rounded box, fan with rotating blades, top louvers, brand dot.
function HeatPump({ x, y, size = 200, opacity = 1, spinning = true, label = true }) {
  const t = useTime();
  const rot = spinning ? (t * 90) % 360 : 0;
  const w = size, h = size * 0.84;
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: w, height: h,
      transform: 'translate(-50%, -50%)', opacity,
    }}>
      <svg width={w} height={h} viewBox="0 0 100 84" style={{ overflow: 'visible' }}>
        {/* shadow */}
        <ellipse cx="50" cy="82" rx="36" ry="2.2" fill={VC.ink} opacity="0.5" />
        {/* legs */}
        <line x1="22" y1="76" x2="22" y2="82" stroke={VC.muted} strokeWidth="1.2" />
        <line x1="78" y1="76" x2="78" y2="82" stroke={VC.muted} strokeWidth="1.2" />
        {/* outer chassis */}
        <rect x="14" y="12" width="72" height="64" rx="4" ry="4"
          fill={VC.ink2} stroke={VC.paper} strokeOpacity="0.85" strokeWidth="1.3" />
        {/* top louvers */}
        <g stroke={VC.paper} strokeOpacity="0.55" strokeWidth="0.6">
          <line x1="18" y1="16" x2="82" y2="16" />
          <line x1="18" y1="19" x2="82" y2="19" />
          <line x1="18" y1="22" x2="82" y2="22" />
        </g>
        {/* inner panel (fan housing) */}
        <circle cx="50" cy="48" r="22"
          fill={VC.ink} stroke={VC.paper} strokeOpacity="0.55" strokeWidth="0.8" />
        <circle cx="50" cy="48" r="18"
          fill="none" stroke={VC.paper} strokeOpacity="0.18" strokeWidth="0.4" />
        {/* fan blades */}
        <g transform={`rotate(${rot} 50 48)`}>
          {[0, 120, 240].map((a) => (
            <path key={a}
              d="M 50 48 Q 56 36 62 32 Q 56 38 50 40 Z"
              transform={`rotate(${a} 50 48)`}
              fill={VC.paper} fillOpacity="0.85"
              stroke={VC.paper} strokeOpacity="0.5" strokeWidth="0.3" />
          ))}
          <circle cx="50" cy="48" r="2.4" fill={VC.copper} />
        </g>
        {/* status LED + brand dot */}
        <circle cx="22" cy="70" r="1.4" fill={VC.copper}
          opacity={0.5 + 0.5 * Math.abs(Math.sin(t * 2))} />
        {label && (
          <g>
            <rect x="60" y="68" width="20" height="4.4" rx="1" ry="1"
              fill={VC.ink3} stroke={VC.paper} strokeOpacity="0.4" strokeWidth="0.2" />
            <text x="70" y="71.4" fontFamily={VC.fontMono} fontSize="2.4"
              fill={VC.muted} textAnchor="middle" letterSpacing="0.1em">VIKING</text>
          </g>
        )}
      </svg>
    </div>
  );
}

// ── Static-position house with optional thermostat readout ────────────────
function CopHouse({ x, y, size = 280, drawT = 1, opacity = 1, comfort = true, indoorTemp = '21°' }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: size, height: size,
      transform: 'translate(-50%, -50%)', opacity,
    }}>
      <svg width={size} height={size} viewBox="0 0 100 100" style={{ overflow: 'visible' }}>
        {/* roof */}
        <path d="M 14 50 L 50 22 L 86 50" fill="none"
          stroke={VC.paper} strokeWidth="1.4" strokeLinejoin="round" strokeLinecap="round"
          pathLength={1} strokeDasharray={1} strokeDashoffset={1 - drawT * 0.45} />
        {/* walls */}
        <path d="M 22 50 L 22 80 L 78 80 L 78 50" fill="none"
          stroke={VC.paper} strokeWidth="1.4" strokeLinejoin="round" strokeLinecap="round"
          pathLength={1} strokeDasharray={1} strokeDashoffset={1 - smooth(ramp(drawT, 0.4, 1)) * 0.55} />
        <path d="M 22 50 L 22 80 L 78 80 L 78 50 L 50 22 Z"
          fill={VC.ink2} opacity={0.4 * drawT} />
        {/* door */}
        <rect x="44" y="64" width="9" height="16"
          fill="none" stroke={VC.line} strokeWidth="0.5" opacity={drawT} />
        <circle cx="51" cy="72" r="0.5" fill={VC.copper} opacity={drawT} />
        {/* window */}
        <rect x="58" y="56" width="12" height="10"
          fill={VC.ink3} stroke={VC.line} strokeWidth="0.5" opacity={drawT} />
        <line x1="64" y1="56" x2="64" y2="66" stroke={VC.line} strokeWidth="0.3" opacity={drawT} />
        <line x1="58" y1="61" x2="70" y2="61" stroke={VC.line} strokeWidth="0.3" opacity={drawT} />

        {/* comfort core */}
        {comfort && (
          <g opacity={drawT}>
            <circle cx="34" cy="62" r="9" fill={VC.copper} opacity="0.13" />
            <circle cx="34" cy="62" r="6.5" fill={VC.copper} opacity="0.22" />
            <text x="34" y="63.5" fontFamily={VC.fontSans} fontWeight="600" fontSize="6"
              fill={VC.paper} textAnchor="middle" letterSpacing="-0.04em">{indoorTemp}</text>
          </g>
        )}
      </svg>
    </div>
  );
}

// ── Weather tile (sun / cloud / etc) ───────────────────────────────────────
function Weather({ x, y, kind = 'sun', size = 80, opacity = 1, value }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: size, height: size,
      transform: 'translate(-50%, -50%)', opacity,
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
    }}>
      <svg width={size * 0.8} height={size * 0.8} viewBox="0 0 40 40" style={{ overflow: 'visible' }}>
        {kind === 'sun' && (
          <g>
            <circle cx="20" cy="20" r="8" fill={VC.yellow} />
            {Array.from({ length: 8 }).map((_, i) => {
              const a = (i * 45) * Math.PI / 180;
              const x1 = 20 + Math.cos(a) * 12, y1 = 20 + Math.sin(a) * 12;
              const x2 = 20 + Math.cos(a) * 16, y2 = 20 + Math.sin(a) * 16;
              return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2}
                stroke={VC.yellow} strokeWidth="1.6" strokeLinecap="round" />;
            })}
          </g>
        )}
        {kind === 'cloud' && (
          <g>
            <ellipse cx="14" cy="24" rx="6" ry="5" fill={VC.muted} opacity="0.8" />
            <ellipse cx="22" cy="22" rx="8" ry="6" fill={VC.muted} opacity="0.85" />
            <ellipse cx="28" cy="25" rx="6" ry="5" fill={VC.muted} opacity="0.75" />
          </g>
        )}
        {kind === 'cold' && (
          <g stroke={VC.blue} strokeWidth="2" strokeLinecap="round" fill="none">
            <line x1="20" y1="8" x2="20" y2="32" />
            <line x1="9" y1="20" x2="31" y2="20" />
            <line x1="11.6" y1="11.6" x2="28.4" y2="28.4" />
            <line x1="28.4" y1="11.6" x2="11.6" y2="28.4" />
          </g>
        )}
      </svg>
      {value && (
        <div style={{
          fontFamily: VC.fontMono, fontSize: 14, color: VC.paper, letterSpacing: '0.04em',
        }}>{value}</div>
      )}
    </div>
  );
}

// ── Thermostat dial ───────────────────────────────────────────────────────
function Thermostat({ x, y, size = 160, opacity = 1, value = 21 }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: size, height: size,
      transform: 'translate(-50%, -50%)', opacity,
    }}>
      <svg width={size} height={size} viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="46" fill={VC.ink2} stroke={VC.line} strokeWidth="0.8" />
        <circle cx="50" cy="50" r="38" fill="none" stroke={VC.paper} strokeOpacity="0.18" strokeWidth="0.5" />
        {/* tick marks around */}
        {Array.from({ length: 24 }).map((_, i) => {
          const a = (i * 360 / 24 - 90) * Math.PI / 180;
          const r1 = 40, r2 = 44;
          const x1 = 50 + Math.cos(a) * r1, y1 = 50 + Math.sin(a) * r1;
          const x2 = 50 + Math.cos(a) * r2, y2 = 50 + Math.sin(a) * r2;
          return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2}
            stroke={VC.muted} strokeWidth="0.6" opacity={0.4 + (i % 6 === 0 ? 0.6 : 0)} />;
        })}
        <text x="50" y="48" fontFamily={VC.fontSans} fontWeight="500" fontSize="22"
          fill={VC.paper} textAnchor="middle" letterSpacing="-0.04em">{value}°</text>
        <text x="50" y="62" fontFamily={VC.fontMono} fontSize="6"
          fill={VC.copper} textAnchor="middle" letterSpacing="0.16em">KOMFORT</text>
      </svg>
    </div>
  );
}

// ── Vertical flow temperature gauge (thermometer-ish) ─────────────────────
function FlowGauge({ x, y, height = 460, value, fromValue, toValue, opacity = 1, label = 'FREMLØB' }) {
  // value: current temperature (°C). Range maps 30..60 °C to bottom..top of the tube.
  const min = 28, max = 62;
  const pct = (v) => Math.max(0, Math.min(1, (v - min) / (max - min)));
  const tubeH = height - 110;
  const fillH = tubeH * pct(value);
  // colour interpolates blue → copper as temp rises
  const blend = pct(value);
  const fillColor = `oklch(0.66 0.13 ${lerp(220, 40, blend)})`;
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: 200, height,
      transform: 'translate(-50%, 0)', opacity,
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
    }}>
      <div style={{
        fontFamily: VC.fontMono, fontSize: 13, letterSpacing: '0.18em',
        color: VC.muted, textTransform: 'uppercase',
      }}>{label}</div>
      <svg width="200" height={tubeH + 60} viewBox={`0 0 60 ${tubeH + 60}`}>
        {/* tube */}
        <rect x="22" y="10" width="16" height={tubeH} rx="8" ry="8"
          fill={VC.ink2} stroke={VC.line} strokeWidth="0.8" />
        {/* fill */}
        <rect x="24" y={10 + tubeH - fillH} width="12" height={fillH}
          rx="6" ry="6" fill={fillColor} />
        {/* bulb */}
        <circle cx="30" cy={tubeH + 22} r="14" fill={fillColor} stroke={VC.line} strokeWidth="0.8" />
        {/* scale ticks */}
        {[30, 35, 40, 45, 50, 55, 60].map((v) => {
          const yy = 10 + tubeH - tubeH * pct(v);
          return (
            <g key={v}>
              <line x1="42" y1={yy} x2="48" y2={yy} stroke={VC.muted} strokeWidth="0.5" />
              <text x="50" y={yy + 1.5} fontFamily={VC.fontMono} fontSize="3"
                fill={VC.muted} letterSpacing="0.05em">{v}</text>
            </g>
          );
        })}
      </svg>
      <div style={{
        fontFamily: VC.fontSans, fontWeight: 600, fontSize: 64,
        letterSpacing: '-0.025em', color: VC.paper, lineHeight: 1,
      }}>{value.toFixed(0)}<span style={{ color: VC.copper, fontSize: 32, marginLeft: 4 }}>°C</span></div>
      {fromValue != null && toValue != null && value !== fromValue && (
        <div style={{
          fontFamily: VC.fontMono, fontSize: 13, color: VC.copper, letterSpacing: '0.1em',
          textTransform: 'uppercase', opacity: 0.85,
        }}>{fromValue}° → {toValue}°</div>
      )}
    </div>
  );
}

// ── Generic plot area (axes, grid, helper for curves) ─────────────────────
function PlotFrame({ x, y, w, h, opacity = 1, children, xLabel, yLeftLabel, yRightLabel, xTicks = [] }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: w, height: h, opacity,
      pointerEvents: 'none',
    }}>
      <svg width={w} height={h} style={{ overflow: 'visible' }}>
        {/* horizontal grid lines */}
        {[0, 0.25, 0.5, 0.75, 1].map((p, i) => (
          <line key={i} x1="0" x2={w} y1={p * h} y2={p * h}
            stroke={VC.line} strokeWidth="0.6" opacity={i === 4 ? 1 : 0.45} />
        ))}
        {/* vertical x ticks */}
        {xTicks.map((t, i) => (
          <g key={i}>
            <line x1={t.x} x2={t.x} y1={h - 4} y2={h + 4}
              stroke={VC.muted} strokeWidth="0.6" opacity="0.6" />
            <text x={t.x} y={h + 18} fontFamily={VC.fontMono} fontSize="12"
              fill={VC.muted} textAnchor="middle" letterSpacing="0.06em">{t.label}</text>
          </g>
        ))}
        {children}
      </svg>
      {yLeftLabel && (
        <div style={{
          position: 'absolute', left: -6, top: -22,
          fontFamily: VC.fontMono, fontSize: 12, color: VC.muted,
          letterSpacing: '0.12em', textTransform: 'uppercase',
        }}>{yLeftLabel}</div>
      )}
      {yRightLabel && (
        <div style={{
          position: 'absolute', right: 0, top: -22,
          fontFamily: VC.fontMono, fontSize: 12, color: VC.muted,
          letterSpacing: '0.12em', textTransform: 'uppercase',
        }}>{yRightLabel}</div>
      )}
      {xLabel && (
        <div style={{
          position: 'absolute', left: w / 2, bottom: -42, transform: 'translateX(-50%)',
          fontFamily: VC.fontMono, fontSize: 12, color: VC.mutedDim,
          letterSpacing: '0.18em', textTransform: 'uppercase',
        }}>{xLabel}</div>
      )}
    </div>
  );
}

// Build a path string from points array
function buildPath(points) {
  if (!points.length) return '';
  return points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0]} ${p[1]}`).join(' ');
}

// ── Power consumption graph: spiky vs smooth comparison ───────────────────
// Conventional: many cycles, each ~5 min on (sharp startup → run plateau → drop).
// VikingHeat:   few cycles, each ~30-45 min on (smooth ramp up → plateau → ramp down).
// drawT 0..1 reveals from left to right.
function PowerGraph({ x, y, w, h, drawT = 1, opacity = 1, variant = 'spiky' }) {
  const N = 360;
  // Window represents ~6 hours of operation (360 minutes), 1 sample per minute.

  // Conventional cycle: 30 min period, 5 min on (with startup spike), 25 min off.
  const conv = (min) => {
    const period = 30;
    const on = 5;
    const phase = min % period;
    if (phase >= on) return 0.04;            // off (small standby)
    // Within the 5-min on-window:
    // 0..0.5 min: steep startup spike from 0 → 1.0
    // 0.5..1.0 min: drop from 1.0 → 0.55
    // 1.0..4.5 min: stay at ~0.55 with tiny modulation
    // 4.5..5.0 min: drop from 0.55 → 0
    if (phase < 0.5)        return phase / 0.5;
    if (phase < 1.0)        return 1.0 - (phase - 0.5) / 0.5 * 0.45;
    if (phase < 4.5)        return 0.55 + 0.03 * Math.sin(phase * 4);
    /* 4.5..5.0 */          return 0.55 - (phase - 4.5) / 0.5 * 0.55;
  };

  // VikingHeat cycle: ~80 min period, ~38 min on (smooth ramp), ~42 min off.
  const vh = (min) => {
    // 4 cycles staggered with slightly varied on-times (35..45 min)
    const cycles = [
      { start: 12,  end: 50  },   // 38 min on
      { start: 110, end: 152 },   // 42 min on
      { start: 200, end: 245 },   // 45 min on
      { start: 295, end: 330 },   // 35 min on
    ];
    const baseline = 0.06;
    for (const c of cycles) {
      if (min < c.start || min > c.end) continue;
      const dur = c.end - c.start;
      const phase = min - c.start;
      const ramp = 4; // minutes for ramp up / down
      const plateau = 0.50;
      let v;
      if (phase < ramp) v = (phase / ramp) * plateau;
      else if (phase > dur - ramp) v = ((dur - phase) / ramp) * plateau;
      else v = plateau + 0.025 * Math.sin(phase * 0.18);
      return Math.max(baseline, v);
    }
    return baseline;
  };

  const series = [];
  for (let i = 0; i < N; i++) {
    const min = (i / (N - 1)) * 360;
    const px = (i / (N - 1)) * w;
    const v = variant === 'smooth' ? vh(min) : conv(min);
    series.push([px, h - v * h * 0.92]);
  }

  const cut = Math.max(2, Math.floor(N * drawT));
  const draw = series.slice(0, cut);

  const stroke = variant === 'smooth' ? VC.copper : VC.muted;
  const strokeW = variant === 'smooth' ? 3 : 2;
  const fillCol = variant === 'smooth' ? VC.copper : VC.muted;
  const fillOp = variant === 'smooth' ? 0.12 : 0.10;

  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: w, height: h, opacity,
    }}>
      <svg width={w} height={h} style={{ overflow: 'visible' }}>
        {/* baseline */}
        <line x1="0" x2={w} y1={h} y2={h} stroke={VC.line} strokeWidth="0.8" />
        {/* horizontal grid */}
        {[0.25, 0.5, 0.75].map((p, i) => (
          <line key={i} x1="0" x2={w} y1={p * h} y2={p * h}
            stroke={VC.line} strokeWidth="0.5" opacity="0.5" />
        ))}
        {/* shaded fill */}
        {draw.length > 1 && (
          <path d={`${buildPath(draw)} L ${draw[draw.length - 1][0]} ${h} L 0 ${h} Z`}
            fill={fillCol} opacity={fillOp} />
        )}
        {/* curve */}
        <path d={buildPath(draw)} fill="none"
          stroke={stroke} strokeWidth={strokeW}
          strokeLinejoin="round" strokeLinecap="round" />
      </svg>
    </div>
  );
}

Object.assign(window, {
  HeatPump, CopHouse, Weather, Thermostat,
  FlowGauge, PlotFrame, buildPath, PowerGraph,
});
