/* global React */
// Progressive Bike-SVG — baut sich Komponente für Komponente auf

const BIKE_VIEWBOX = "0 0 1200 720";

// Per-frame visual params: dropouts, BB position, geometry hints.
// All paths are scaled within the viewBox; rear axle ≈ (260, 500), front axle ≈ (940, 500).
function frameDims(frame) {
  if (!frame) return { travel: 140, hardtail: false, ebike: false };
  return {
    travel: frame.travel_mm || 140,
    hardtail: !!frame.is_hardtail,
    ebike: frame.id?.startsWith("frame_emtb"),
    color: frame.material === "carbon" ? "#1a1a1a" : "#2a2a2a",
    accent: frame.material === "carbon" ? "#0a0a0a" : "#3a3a3a"
  };
}

// Layer wrapper — fades in when visible, ghosted dashed outline otherwise
function Layer({ visible, ghost = true, children, opacity = 1 }) {
  return (
    <g style={{
      opacity: visible ? opacity : (ghost ? 0.12 : 0),
      transition: "opacity 600ms cubic-bezier(0.2,0.8,0.2,1)",
      filter: visible ? "none" : "saturate(0)"
    }}>
      {children}
    </g>
  );
}

function BikeSVG({ frame, build, visible }) {
  const f = frameDims(frame);
  const v = visible || {};
  const showFrame = true; // Frame always visible once chosen
  const showFork = v.fork || v.wheels;
  const showWheels = v.wheels;
  const showTires = v.tires || v.wheels;
  const showDrivetrain = v.drivetrain;
  const showBrakes = v.brakes;
  const showCockpit = v.cockpit;
  const showSaddle = v.saddle;
  const showDropper = v.dropper;
  const showShock = v.shock || (v.fork && !f.hardtail);

  // Fork travel scales the visual fork length
  const forkTravel = build?.fork?.travel_mm || f.travel;
  const forkOffset = (forkTravel - 100) * 0.4; // visual delta

  // Wheel size affects circle radius
  const wheelR = (frame?.wheel_size === 27.5) ? 165 : 175;

  return (
    <svg viewBox={BIKE_VIEWBOX} style={{ width: "100%", height: "100%", maxHeight: "100%" }}>
      <defs>
        <linearGradient id="frameGrad" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={f.color} />
          <stop offset="100%" stopColor={f.accent} />
        </linearGradient>
        <linearGradient id="rimGrad" x1="0" x2="1" y1="0" y2="0">
          <stop offset="0%" stopColor="#444" />
          <stop offset="50%" stopColor="#888" />
          <stop offset="100%" stopColor="#444" />
        </linearGradient>
        <pattern id="tireTread" x="0" y="0" width="14" height="14" patternUnits="userSpaceOnUse">
          <rect width="14" height="14" fill="#0c0c0c" />
          <rect x="3" y="3" width="8" height="3" fill="#1a1a1a" />
          <rect x="3" y="8" width="8" height="3" fill="#1a1a1a" />
        </pattern>
      </defs>

      {/* Ground shadow */}
      <ellipse cx="600" cy="660" rx="420" ry="14" fill="rgba(0,0,0,0.45)" />

      {/* Wheels (rims) — rear at (260,500), front at (940,500 - forkOffset) */}
      <Layer visible={showWheels}>
        {/* Rear */}
        <circle cx="260" cy="500" r={wheelR - 30} fill="none" stroke="url(#rimGrad)" strokeWidth="6" />
        {/* spokes */}
        {[...Array(16)].map((_, i) => {
          const a = (i / 16) * Math.PI * 2;
          return <line key={`rs${i}`} x1="260" y1="500"
            x2={260 + Math.cos(a) * (wheelR - 32)}
            y2={500 + Math.sin(a) * (wheelR - 32)}
            stroke="#666" strokeWidth="1" />;
        })}
        <circle cx="260" cy="500" r="14" fill="#1a1a1a" stroke="#3a3a3a" strokeWidth="1.5" />

        {/* Front */}
        <circle cx="940" cy={500 - forkOffset} r={wheelR - 30} fill="none" stroke="url(#rimGrad)" strokeWidth="6" />
        {[...Array(16)].map((_, i) => {
          const a = (i / 16) * Math.PI * 2;
          return <line key={`fs${i}`} x1="940" y1={500 - forkOffset}
            x2={940 + Math.cos(a) * (wheelR - 32)}
            y2={500 - forkOffset + Math.sin(a) * (wheelR - 32)}
            stroke="#666" strokeWidth="1" />;
        })}
        <circle cx="940" cy={500 - forkOffset} r="14" fill="#1a1a1a" stroke="#3a3a3a" strokeWidth="1.5" />
      </Layer>

      {/* Tires (thick black ring) */}
      <Layer visible={showTires}>
        <circle cx="260" cy="500" r={wheelR - 8} fill="none" stroke="url(#tireTread)" strokeWidth="34" />
        <circle cx="940" cy={500 - forkOffset} r={wheelR - 8} fill="none" stroke="url(#tireTread)" strokeWidth="34" />
      </Layer>

      {/* Brakes (rotors) */}
      <Layer visible={showBrakes}>
        <circle cx="260" cy="500" r="58" fill="none" stroke="#999" strokeWidth="2" />
        <circle cx="260" cy="500" r="58" fill="none" stroke="#666" strokeWidth="1" strokeDasharray="3 6" />
        <circle cx="940" cy={500 - forkOffset} r="68" fill="none" stroke="#999" strokeWidth="2" />
        <circle cx="940" cy={500 - forkOffset} r="68" fill="none" stroke="#666" strokeWidth="1" strokeDasharray="3 6" />
        {/* Calipers */}
        <rect x="246" y="420" width="28" height="24" fill="#7a1818" />
        <rect x="926" y={420 - forkOffset} width="28" height="24" fill="#7a1818" />
      </Layer>

      {/* Frame — main triangle: BB at (450,490), head tube top at (820,260), seat tube top at (560,250) */}
      <Layer visible={showFrame} opacity={1}>
        {/* Down tube: BB → head tube */}
        <path d="M 450 490 L 820 280 L 840 300 L 470 510 Z" fill="url(#frameGrad)" />
        {/* Top tube: seat tube top → head tube top */}
        <path d="M 560 250 L 820 260 L 820 280 L 560 270 Z" fill="url(#frameGrad)" />
        {/* Seat tube: BB → seat clamp */}
        <path d="M 450 490 L 470 490 L 565 250 L 555 250 Z" fill="url(#frameGrad)" />
        {/* Chainstay: BB → rear dropout */}
        <path d="M 450 490 L 260 500 L 260 510 L 450 500 Z" fill={f.accent} />
        {/* Seatstay: rear dropout → seat tube top */}
        {!f.hardtail
          ? <path d="M 260 500 L 380 360 L 392 366 L 268 504 Z" fill={f.accent} />
          : <path d="M 260 500 L 560 260 L 568 268 L 268 504 Z" fill={f.accent} />}
        {/* Head tube */}
        <rect x="810" y="240" width="20" height="60" fill={f.accent} rx="2" />
        {/* BB shell */}
        <circle cx="450" cy="490" r="22" fill="#0a0a0a" stroke={f.accent} strokeWidth="2" />
        {/* Brand mark */}
        <text x="640" y="320" fill="rgba(255,255,255,0.18)"
          fontSize="18" fontWeight="700" letterSpacing="3"
          fontFamily="var(--font-sans)">BIKEFORGE</text>
      </Layer>

      {/* Rear shock — runs from front of seat tube down to chainstay pivot */}
      <Layer visible={showShock} ghost={!f.hardtail}>
        {!f.hardtail && (
          <>
            <rect x="475" y="335" width="80" height="14" fill="#5a5a5a" rx="2" transform="rotate(20 515 342)" />
            <rect x="490" y="338" width="55" height="8" fill="#888" rx="1" transform="rotate(20 517 342)" />
          </>
        )}
      </Layer>

      {/* Motor (ebike only) — at BB */}
      {f.ebike && (
        <Layer visible={showFrame}>
          <rect x="395" y="465" width="120" height="58" rx="8" fill="#222" stroke={f.accent} strokeWidth="2" />
          <text x="455" y="500" fill="rgba(255,255,255,0.4)" textAnchor="middle"
            fontSize="11" fontWeight="700" letterSpacing="2">E·DRIVE</text>
        </Layer>
      )}

      {/* Fork — head tube bottom (820,300) → front axle (940, 500-forkOffset) */}
      <Layer visible={showFork}>
        {/* Crown */}
        <rect x="800" y="296" width="40" height="18" fill="#3a3a3a" rx="2" />
        {/* Stanchions */}
        <path d={`M 808 314 L 936 ${496 - forkOffset} L 944 ${496 - forkOffset} L 816 314 Z`}
          fill="#dadada" />
        <path d={`M 822 314 L 948 ${496 - forkOffset} L 956 ${496 - forkOffset} L 830 314 Z`}
          fill="#dadada" />
        {/* Lower legs */}
        <path d={`M 920 ${440 - forkOffset} L 960 ${440 - forkOffset} L 962 ${506 - forkOffset} L 918 ${506 - forkOffset} Z`}
          fill="#1a1a1a" />
      </Layer>

      {/* Drivetrain: cassette at rear hub, chainring at BB, chain line, crank arm */}
      <Layer visible={showDrivetrain}>
        {/* Cassette */}
        <circle cx="260" cy="500" r="38" fill="none" stroke="#999" strokeWidth="2" />
        <circle cx="260" cy="500" r="32" fill="none" stroke="#777" strokeWidth="1.5" />
        <circle cx="260" cy="500" r="26" fill="none" stroke="#555" strokeWidth="1.5" />
        {/* Chainring */}
        <circle cx="450" cy="490" r="40" fill="none" stroke="#bbb" strokeWidth="3" />
        <circle cx="450" cy="490" r="40" fill="none" stroke="#666" strokeWidth="0.8" strokeDasharray="2 3" />
        {/* Crank arm */}
        <rect x="448" y="490" width="76" height="10" fill="#3a3a3a" rx="1" transform="rotate(35 450 490)" />
        <circle cx="510" cy="538" r="8" fill="#222" />
        {/* Chain — line from chainring top to cassette top, and bottom return */}
        <line x1="262" y1="462" x2="450" y2="450" stroke="#666" strokeWidth="3" />
        <line x1="260" y1="538" x2="450" y2="530" stroke="#444" strokeWidth="3" />
        {/* Derailleur cage */}
        <path d="M 260 538 L 248 564 L 260 580 L 272 564 Z" fill="#444" />
      </Layer>

      {/* Cockpit: stem + handlebar */}
      <Layer visible={showCockpit}>
        {/* Stem */}
        <rect x="800" y="220" width="60" height="22" fill="#2a2a2a" rx="2" />
        {/* Steerer cap */}
        <rect x="816" y="208" width="28" height="14" fill="#3a3a3a" rx="2" />
        {/* Handlebar (front view ish — wide bar represented as horizontal pill) */}
        <rect x="770" y="210" width="120" height="10" fill="#1a1a1a" rx="5" />
        {/* Grips */}
        <rect x="760" y="208" width="14" height="14" fill="#0a0a0a" rx="2" />
        <rect x="886" y="208" width="14" height="14" fill="#0a0a0a" rx="2" />
      </Layer>

      {/* Dropper post (between seat tube top and saddle) */}
      <Layer visible={showDropper || showSaddle}>
        <rect x="552" y="200" width="16" height="60" fill="#3a3a3a" rx="2" />
        {showDropper && (
          <rect x="554" y="205" width="12" height="8" fill="var(--accent, #da291c)" rx="1" />
        )}
      </Layer>

      {/* Saddle */}
      <Layer visible={showSaddle}>
        <path d="M 510 192 L 610 188 L 622 200 L 610 208 L 510 204 Z" fill="#1a1a1a" />
        <path d="M 510 196 L 610 192 L 612 198 L 610 202 L 510 200 Z" fill="#2a2a2a" />
      </Layer>

      {/* Idle hint when nothing yet */}
      {!showFork && !showWheels && (
        <text x="600" y="660" textAnchor="middle"
          fill="rgba(255,255,255,0.45)" fontSize="13" fontWeight="600"
          letterSpacing="2" fontFamily="var(--font-sans)">
          KOMPONENTEN AUSWÄHLEN — DAS BIKE BAUT SICH AUF
        </text>
      )}
    </svg>
  );
}

window.BikeSVG = BikeSVG;
