/* Nexaro fuel-scroll section. Motion is tied to blend composition and readout state. */

(function () {
  if (document.getElementById("fuel-redesign-kf")) return;
  const style = document.createElement("style");
  style.id = "fuel-redesign-kf";
  style.textContent = `
    @keyframes nxf-wipe {
      from { clip-path: inset(0 0 100% 0); }
      to { clip-path: inset(0 0 0 0); }
    }
    @keyframes nxf-up {
      from { opacity: 0; transform: translateY(14px); }
      to { opacity: 1; transform: translateY(0); }
    }
  `;
  document.head.appendChild(style);
})();

const FUEL_ITEMS = [
  {
    name: "Diesel B7",
    spec: "EN 590",
    tag: "B7",
    blend: 7,
    blendLabel: "Biodiesel FAME",
    baseLabel: "Fossiler Diesel",
    accent: "199, 145, 58",
    note: "Straßendiesel mit bis zu 7% Biodiesel, verfügbar in Saisonqualitäten und bei der Beladung zertifiziert.",
  },
  {
    name: "Benzin E5",
    spec: "EN 228",
    tag: "E5",
    blend: 5,
    blendLabel: "Ethanol",
    baseLabel: "Fossiles Benzin",
    accent: "204, 157, 80",
    note: "Super 95 mit bis zu 5% Ethanol, verfügbar für ältere Fahrzeuge und leistungsstarke Motoren.",
  },
  {
    name: "Benzin E10",
    spec: "EN 228",
    tag: "E10",
    blend: 10,
    blendLabel: "Ethanol",
    baseLabel: "Fossiles Benzin",
    accent: "191, 132, 62",
    note: "Super E10 mit bis zu 10% Ethanol und geringerem fossilem Anteil für den Großteil der aktiven Flotte.",
  },
  {
    name: "HVO 100",
    spec: "EN 15940",
    tag: "HVO",
    blend: 100,
    blendLabel: "Erneuerbares HVO",
    baseLabel: "Fossiler Anteil",
    accent: "127, 192, 160",
    note: "Paraffinischer erneuerbarer Diesel mit niedrigerer CO2-Bilanz und Drop-in-Nutzung für kompatible Dieselmotoren.",
  },
  {
    name: "Heizöl",
    spec: "DIN 51603-1",
    tag: "Öl",
    blend: 0,
    blendLabel: "Additivpaket",
    baseLabel: "Schwefelarmes Heizöl",
    accent: "227, 194, 130",
    note: "Schwefelarmes Heizöl für Haushalte, Wohnungswirtschaft und gewerbliche Standorte.",
  },
];

function getFuelViewportHeight() {
  return window.visualViewport?.height || document.documentElement.clientHeight || window.innerHeight;
}

function fuelMix(a, b, t) {
  return a.map((value, index) => value + (b[index] - value) * t);
}

function BlendColumn({ stateRef }) {
  const ref = React.useRef(null);

  React.useEffect(() => {
    const canvas = ref.current;
    const wrap = canvas.parentElement;
    const dpr = Math.min(2, window.devicePixelRatio || 1);
    const ctx = canvas.getContext("2d");
    const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    let width = 0;
    let height = 0;
    let raf;

    const resize = () => {
      width = wrap.clientWidth;
      height = wrap.clientHeight;
      canvas.width = width * dpr;
      canvas.height = height * dpr;
    };

    const draw = () => {
      const state = stateRef.current;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      ctx.clearRect(0, 0, width, height);

      const columnWidth = Math.min(width * 0.46, 136);
      const x = (width - columnWidth) / 2;
      const top = height * 0.07;
      const bottom = height - top;
      const columnHeight = bottom - top;
      const radius = 5;

      ctx.strokeStyle = "rgba(255,255,255,0.18)";
      ctx.lineWidth = 1;
      ctx.font = "500 10px Ubuntu, sans-serif";
      ctx.textAlign = "right";
      ctx.textBaseline = "middle";

      for (let index = 0; index <= 10; index += 1) {
        const y = bottom - (columnHeight * index) / 10;
        const long = index % 5 === 0;
        ctx.beginPath();
        ctx.moveTo(x - 14, y);
        ctx.lineTo(x - (long ? 24 : 18), y);
        ctx.stroke();
        if (long) {
          ctx.fillStyle = "rgba(255,255,255,0.42)";
          ctx.fillText(String(index * 10), x - 30, y);
        }
      }

      function tube() {
        const r = Math.min(radius, columnWidth / 2);
        ctx.beginPath();
        ctx.moveTo(x + r, top);
        ctx.arcTo(x + columnWidth, top, x + columnWidth, bottom, r);
        ctx.arcTo(x + columnWidth, bottom, x, bottom, r);
        ctx.arcTo(x, bottom, x, top, r);
        ctx.arcTo(x, top, x + columnWidth, top, r);
        ctx.closePath();
      }

      tube();
      ctx.fillStyle = "rgba(255,255,255,0.025)";
      ctx.fill();

      ctx.save();
      tube();
      ctx.clip();

      const blend = Math.max(0, Math.min(1, state.blend));
      const blendTop = bottom - columnHeight * blend;
      const baseGradient = ctx.createLinearGradient(0, top, 0, bottom);
      baseGradient.addColorStop(0, "rgba(65, 91, 126, 0.55)");
      baseGradient.addColorStop(1, "rgba(15, 32, 65, 0.88)");
      if (blend < 0.999) {
        ctx.fillStyle = baseGradient;
        ctx.fillRect(x, top, columnWidth, blendTop - top);
      }

      const [red, green, blue] = state.rgb;
      if (blend > 0.001) {
        const blendGradient = ctx.createLinearGradient(0, blendTop, 0, bottom);
        blendGradient.addColorStop(0, `rgba(${red},${green},${blue},0.92)`);
        blendGradient.addColorStop(1, `rgba(${red},${green},${blue},0.58)`);
        ctx.fillStyle = blendGradient;
        ctx.fillRect(x, blendTop, columnWidth, bottom - blendTop);
      }

      if (blend > 0.001 && blend < 0.999) {
        ctx.fillStyle = `rgba(${red},${green},${blue},0.92)`;
        ctx.fillRect(x, blendTop - 1, columnWidth, 2);
      }

      if (!reduce) {
        const scanY = top + ((state.time * 0.12) % 1) * columnHeight;
        const scan = ctx.createLinearGradient(0, scanY - 24, 0, scanY + 24);
        scan.addColorStop(0, "rgba(255,255,255,0)");
        scan.addColorStop(0.5, "rgba(255,255,255,0.07)");
        scan.addColorStop(1, "rgba(255,255,255,0)");
        ctx.fillStyle = scan;
        ctx.fillRect(x, scanY - 24, columnWidth, 48);
      }

      const highlight = ctx.createLinearGradient(x, 0, x + columnWidth * 0.38, 0);
      highlight.addColorStop(0, "rgba(255,255,255,0.1)");
      highlight.addColorStop(1, "rgba(255,255,255,0)");
      ctx.fillStyle = highlight;
      ctx.fillRect(x, top, columnWidth * 0.38, columnHeight);
      ctx.restore();

      tube();
      ctx.strokeStyle = "rgba(255,255,255,0.24)";
      ctx.lineWidth = 1.2;
      ctx.stroke();

      if (!reduce) raf = requestAnimationFrame(draw);
    };

    resize();
    const observer = new ResizeObserver(resize);
    observer.observe(wrap);
    if (reduce) draw();
    else raf = requestAnimationFrame(draw);

    return () => {
      cancelAnimationFrame(raf);
      observer.disconnect();
    };
  }, []);

  return <canvas ref={ref} style={{ display: "block", width: "100%", height: "100%" }} />;
}

function ScrollFuels() {
  const ref = React.useRef(null);
  const initialRgb = FUEL_ITEMS[0].accent.split(",").map(Number);
  const stateRef = React.useRef({ blend: FUEL_ITEMS[0].blend / 100, rgb: initialRgb, time: 0 });
  const targetRef = React.useRef({ blend: FUEL_ITEMS[0].blend / 100, rgb: initialRgb });
  const stepRef = React.useRef(0);
  const progressRef = React.useRef(0);
  const rafRef = React.useRef(0);
  const [step, setStep] = React.useState(0);
  const [progress, setProgress] = React.useState(0);
  const [shownBlend, setShownBlend] = React.useState(FUEL_ITEMS[0].blend);

  React.useEffect(() => {
    let raf;
    const start = performance.now();
    const tick = (now) => {
      const state = stateRef.current;
      const target = targetRef.current;
      state.blend += (target.blend - state.blend) * 0.09;
      state.rgb = fuelMix(state.rgb, target.rgb, 0.09);
      state.time = (now - start) / 1000;
      setShownBlend((value) => value + ((target.blend * 100) - value) * 0.12);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const setFuel = React.useCallback((index) => {
    const item = FUEL_ITEMS[index];
    if (stepRef.current !== index) {
      stepRef.current = index;
      setStep(index);
    }
    targetRef.current = {
      blend: item.blend / 100,
      rgb: item.accent.split(",").map(Number),
    };
  }, []);

  React.useEffect(() => {
    const apply = () => {
      const el = ref.current;
      if (!el) return;
      const total = el.offsetHeight - getFuelViewportHeight();
      if (total <= 20) return;
      const passed = Math.min(Math.max(-el.getBoundingClientRect().top, 0), total);
      const p = passed / total;
      const index = Math.min(FUEL_ITEMS.length - 1, Math.floor(p * FUEL_ITEMS.length));
      if (Math.abs(progressRef.current - p) > 0.002) {
        progressRef.current = p;
        setProgress(p);
      }
      setFuel(index);
    };

    const schedule = () => {
      if (rafRef.current) return;
      rafRef.current = window.requestAnimationFrame(() => {
        rafRef.current = 0;
        apply();
      });
    };

    window.addEventListener("scroll", schedule, { passive: true });
    window.addEventListener("resize", schedule);
    window.visualViewport?.addEventListener("resize", schedule);
    apply();
    return () => {
      window.removeEventListener("scroll", schedule);
      window.removeEventListener("resize", schedule);
      window.visualViewport?.removeEventListener("resize", schedule);
      if (rafRef.current) window.cancelAnimationFrame(rafRef.current);
    };
  }, [setFuel]);

  const goTo = (index) => {
    const el = ref.current;
    if (!el) return;
    const total = el.offsetHeight - getFuelViewportHeight();
    setFuel(index);
    if (total <= 20) return;
    window.scrollTo({
      top: el.offsetTop + ((index + 0.5) / FUEL_ITEMS.length) * total,
      behavior: "smooth",
    });
  };

  const fuel = FUEL_ITEMS[step];
  const accent = `rgb(${fuel.accent})`;
  const titleKey = `title-${step}`;
  const progressScale = Math.max(0, Math.min(1, progress));

  return (
    <section id="products" ref={ref} className="fuel-scroll" data-theme="dark">
      <div className="fuel-scroll__sticky">
        <div className="fuel-scroll__progress">
          <span style={{ transform: `scaleX(${progressScale})` }} />
        </div>

        <div className="fuel-scroll__layout">
          <div>
            <div className="fuel-scroll__kicker">Produkte / Fünf Kraftstoffe, ein Lieferant</div>
            <div key={titleKey} style={{ overflow: "hidden", marginTop: 18 }}>
              <h2
                className="fuel-scroll__title"
                style={{ animation: "nxf-wipe .75s cubic-bezier(.16,1,.3,1) both" }}
              >
                {fuel.name}
              </h2>
            </div>
            <div
              key={`meta-${step}`}
              className="fuel-scroll__meta"
              style={{ animation: "nxf-up .58s cubic-bezier(.16,1,.3,1) .08s both" }}
            >
              <span className="fuel-scroll__pill" style={{ color: accent }}>{fuel.tag}</span>
              <span className="fuel-scroll__spec">{fuel.spec}</span>
            </div>
            <p
              key={`note-${step}`}
              className="fuel-scroll__note"
              style={{ animation: "nxf-up .62s cubic-bezier(.16,1,.3,1) .12s both" }}
            >
              {fuel.note}
            </p>
          </div>

          <div className="fuel-scroll__instrument">
            <BlendColumn stateRef={stateRef} />
          </div>

          <div>
            <div className="fuel-scroll__readout-label">
              {fuel.blend > 0 ? "Erneuerbarer bzw. Bio-Anteil" : "Zusammensetzung"}
            </div>
            <div className="fuel-scroll__percent">
              <strong>{Math.round(shownBlend)}</strong>
              <span style={{ color: accent }}>%</span>
            </div>

            <div className="fuel-scroll__readout">
              <ReadoutRow swatch={accent} label={fuel.blendLabel} value={`${fuel.blend}%`} />
              <ReadoutRow swatch="rgba(65, 91, 126, 0.85)" label={fuel.baseLabel} value={`${100 - fuel.blend}%`} />
            </div>

            <div className="fuel-scroll__cert">
              <span>Norm {fuel.spec}</span>
              <span style={{ color: accent }}>Zertifiziert</span>
            </div>
          </div>
        </div>

        <div className="fuel-scroll__chapters">
          {FUEL_ITEMS.map((item, index) => {
            const active = index === step;
            const fill = index < step
              ? 1
              : active
                ? Math.max(0, Math.min(1, progress * FUEL_ITEMS.length - index))
                : 0;

            return (
              <button
                key={item.name}
                type="button"
                className={`fuel-scroll__chapter ${active ? "is-active" : ""}`}
                onClick={() => goTo(index)}
              >
                <span className="fuel-scroll__chapter-track">
                  <span
                    className="fuel-scroll__chapter-fill"
                    style={{
                      "--fuel-chapter-color": `rgb(${item.accent})`,
                      transform: `scaleX(${fill})`,
                    }}
                  />
                </span>
                <span className="fuel-scroll__chapter-num">0{index + 1}</span>
                <span className="fuel-scroll__chapter-name">{item.name}</span>
              </button>
            );
          })}
        </div>
      </div>
    </section>
  );
}

function ReadoutRow({ swatch, label, value }) {
  return (
    <div className="fuel-scroll__readout-row">
      <span className="fuel-scroll__swatch" style={{ background: swatch }} />
      <span>{label}</span>
      <span>{value}</span>
    </div>
  );
}

window.ScrollFuels = ScrollFuels;
