import React, { useEffect, useMemo, useRef, useState } from "react";

// --- CONFIG ---
const PRIZES = [
  { label: "Gratis kaffe", type: "win", probability: 0.05 },
  { label: "Rabattkode 10%", type: "win", probability: 0.1 },
  { label: "Ingenting", type: "lose", probability: 0.5 },
  { label: "Nøgle-ring", type: "win", probability: 0.05 },
  { label: "Ingenting", type: "lose", probability: 0.2 },
  { label: "T-shirt", type: "win", probability: 0.03 },
  { label: "Ingenting", type: "lose", probability: 0.07 },
];

// Normalize probabilities and build segments
function buildSegments(config) {
  const total = config.reduce((s, p) => s + p.probability, 0);
  const normalized = config.map((p) => ({ ...p, probability: p.probability / total }));
  return normalized;
}

const SEGMENTS = buildSegments(PRIZES);

function chooseSegment(segments) {
  const r = Math.random();
  let acc = 0;
  for (let i = 0; i < segments.length; i++) {
    acc += segments[i].probability;
    if (r <= acc) return i;
  }
  return segments.length - 1;
}

function emailValid(email) {
  return /[^@\s]+@[^@\s]+\.[^@\s]+/.test(email);
}

function clamp(n, min, max) {
  return Math.max(min, Math.min(max, n));
}

export default function SpinTheWheelApp() {
  const [user, setUser] = useState(() => {
    try {
      const cached = localStorage.getItem("stw_user");
      return cached ? JSON.parse(cached) : null;
    } catch (e) {
      return null;
    }
  });

  const [hasSpun, setHasSpun] = useState(() => {
    try {
      const cached = localStorage.getItem("stw_hasSpun");
      return cached ? JSON.parse(cached) : false;
    } catch (e) {
      return false;
    }
  });

  const [spinning, setSpinning] = useState(false);
  const [result, setResult] = useState(null);
  const [angle, setAngle] = useState(0);
  const [error, setError] = useState("");

  const canvasRef = useRef(null);

  const colors = useMemo(() => {
    // generate alternating colors for segments
    const arr = [];
    for (let i = 0; i < SEGMENTS.length; i++) {
      arr.push(i % 2 === 0 ? "#f4f4f5" : "#e5e7eb"); // zinc-100 / gray-200
    }
    return arr;
  }, []);

  const segmentAngle = (2 * Math.PI) / SEGMENTS.length;

  useEffect(() => {
    drawWheel(angle);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [angle]);

  function drawWheel(rotation = 0) {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    const size = Math.min(canvas.width, canvas.height);
    const radius = size / 2 - 10;
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    ctx.save();
    ctx.translate(canvas.width / 2, canvas.height / 2);
    ctx.rotate(rotation);

    // draw segments
    for (let i = 0; i < SEGMENTS.length; i++) {
      ctx.beginPath();
      ctx.moveTo(0, 0);
      ctx.arc(0, 0, radius, i * segmentAngle, (i + 1) * segmentAngle);
      ctx.closePath();
      ctx.fillStyle = colors[i];
      ctx.fill();

      // text
      ctx.save();
      ctx.rotate(i * segmentAngle + segmentAngle / 2);
      ctx.textAlign = "right";
      ctx.fillStyle = "#111827"; // gray-900
      ctx.font = "bold 14px system-ui, -apple-system, Segoe UI, Roboto, Arial";
      const txt = SEGMENTS[i].label;
      ctx.fillText(txt, radius - 10, 5);
      ctx.restore();
    }

    // center circle
    ctx.beginPath();
    ctx.arc(0, 0, 36, 0, Math.PI * 2);
    ctx.fillStyle = "white";
    ctx.fill();
    ctx.lineWidth = 2;
    ctx.strokeStyle = "#e5e7eb";
    ctx.stroke();

    ctx.restore();

    // pointer at top
    ctx.beginPath();
    const cx = canvas.width / 2;
    const cy = canvas.height / 2;
    ctx.moveTo(cx, cy - radius - 2);
    ctx.lineTo(cx - 10, cy - radius - 22);
    ctx.lineTo(cx + 10, cy - radius - 22);
    ctx.closePath();
    ctx.fillStyle = "#ef4444"; // red-500
    ctx.fill();
    ctx.lineWidth = 2;
    ctx.strokeStyle = "#7f1d1d";
    ctx.stroke();
  }

  function handleSignup(e) {
    e.preventDefault();
    const form = new FormData(e.currentTarget);
    const name = String(form.get("name") || "").trim();
    const email = String(form.get("email") || "").trim().toLowerCase();
    const consent = Boolean(form.get("consent"));

    if (!name) return setError("Skriv dit navn.");
    if (!emailValid(email)) return setError("Indtast en gyldig e‑mail.");
    if (!consent) return setError("Du skal give samtykke til at deltage.");

    setError("");

    const newUser = { name, email, ts: Date.now() };
    setUser(newUser);
    localStorage.setItem("stw_user", JSON.stringify(newUser));

    // Optionally send to backend (uncomment and implement API)
    // fetch("/api/signup", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newUser) });
  }

  function spin() {
    if (spinning) return;
    if (!user) return setError("Udfyld tilmeldingsformularen først.");
    if (hasSpun) return setError("Du har allerede spinnet.");

    setError("");
    setSpinning(true);

    // choose prize index according to probabilities
    const index = chooseSegment(SEGMENTS);

    // compute target angle so that chosen index lands at pointer (top)
    // pointer is at 0 rad in our drawing space; we rotate wheel so that the middle of the segment aligns to pointer
    const segCenter = index * segmentAngle + segmentAngle / 2;

    // add extra spins for flair (5–8 full turns)
    const extraTurns = 5 + Math.floor(Math.random() * 3);

    const finalAngle = extraTurns * 2 * Math.PI + (2 * Math.PI - segCenter);

    const duration = 4500 + Math.random() * 1000; // 4.5–5.5s

    // animate
    const start = performance.now();
    const startAngle = angle % (2 * Math.PI);

    function easeOutCubic(t) {
      return 1 - Math.pow(1 - t, 3);
    }

    function frame(now) {
      const t = clamp((now - start) / duration, 0, 1);
      const eased = easeOutCubic(t);
      const current = startAngle + (finalAngle - startAngle) * eased;
      setAngle(current);
      if (t < 1) {
        requestAnimationFrame(frame);
      } else {
        const prize = SEGMENTS[index];
        setResult(prize);
        setHasSpun(true);
        localStorage.setItem("stw_hasSpun", JSON.stringify(true));
        setSpinning(false);

        // Optionally notify backend of spin + result
        // fetch("/api/spin", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: user.email, prize: prize.label }) });
      }
    }

    requestAnimationFrame(frame);
  }

  function resetForTesting() {
    localStorage.removeItem("stw_hasSpun");
    setHasSpun(false);
    setResult(null);
    setError("");
  }

  return (
    <div className="min-h-screen w-full bg-gradient-to-b from-white to-gray-50 text-gray-900">
      <div className="max-w-4xl mx-auto px-4 py-10">
        <header className="mb-6">
          <h1 className="text-3xl md:text-4xl font-bold tracking-tight">Spin the Wheel 🎡</h1>
          <p className="text-gray-600 mt-2">Skriv dig op med navn og e‑mail for at få ét spin og chancen for at vinde præmier.</p>
        </header>

        {!user ? (
          <form onSubmit={handleSignup} className="bg-white rounded-2xl shadow p-6 grid gap-4 md:grid-cols-2">
            <div className="md:col-span-1">
              <label className="block text-sm font-medium mb-1">Navn</label>
              <input name="name" type="text" className="w-full rounded-xl border border-gray-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Mads Holfort" />
            </div>
            <div className="md:col-span-1">
              <label className="block text-sm font-medium mb-1">E‑mail</label>
              <input name="email" type="email" className="w-full rounded-xl border border-gray-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="mads@example.com" />
            </div>
            <div className="md:col-span-2 flex items-start gap-3">
              <input id="consent" name="consent" type="checkbox" className="mt-1 h-4 w-4" />
              <label htmlFor="consent" className="text-sm text-gray-700">Jeg giver samtykke til at modtage information om konkurrencen og accepterer vilkår og privatlivspolitik.</label>
            </div>
            {error && (
              <div className="md:col-span-2 text-sm text-red-600">{error}</div>
            )}
            <div className="md:col-span-2">
              <button type="submit" className="w-full md:w-auto rounded-xl bg-indigo-600 hover:bg-indigo-700 text-white font-semibold px-5 py-2.5 transition">Tilmeld og gå til hjulet</button>
            </div>
          </form>
        ) : (
          <div className="grid md:grid-cols-2 gap-8 items-center">
            <div className="bg-white rounded-2xl shadow p-6">
              <div className="flex items-center justify-between mb-4">
                <div>
                  <p className="text-sm text-gray-500">Tilmeldt som</p>
                  <p className="font-semibold">{user.name} · {user.email}</p>
                </div>
                <button onClick={resetForTesting} className="text-xs text-gray-500 hover:text-gray-700 underline" title="Nulstil spin (kun til test)">Nulstil</button>
              </div>
              <div className="relative mx-auto" style={{ width: 360, height: 360 }}>
                <canvas ref={canvasRef} width={360} height={360} className="w-full h-full" />
                <div className="absolute inset-0 flex items-center justify-center">
                  <button
                    onClick={spin}
                    disabled={spinning || hasSpun}
                    className={`rounded-full px-6 py-3 text-sm font-semibold shadow ${
                      spinning || hasSpun ? "bg-gray-300 text-gray-600 cursor-not-allowed" : "bg-indigo-600 text-white hover:bg-indigo-700"
                    }`}
                  >
                    {spinning ? "Spinner…" : hasSpun ? "Allerede spinnet" : "SPIN"}
                  </button>
                </div>
              </div>
              {error && <p className="mt-3 text-sm text-red-600">{error}</p>}
            </div>

            <div className="bg-white rounded-2xl shadow p-6">
              <h2 className="text-lg font-semibold mb-2">Præmier & sandsynligheder</h2>
              <ul className="space-y-2">
                {SEGMENTS.map((s, i) => (
                  <li key={i} className="flex items-center justify-between text-sm">
                    <span>{s.label}</span>
                    <span className="tabular-nums text-gray-600">{Math.round(s.probability * 1000) / 10}%</span>
                  </li>
                ))}
              </ul>
              <p className="text-xs text-gray-500 mt-4">Sandsynligheder normaliseres automatisk til 100%. Justér i koden i PRIZES.</p>
            </div>
          </div>
        )}

        {/* Result modal */}
        {result && (
          <div className="fixed inset-0 bg-black/40 flex items-center justify-center p-4">
            <div className="bg-white rounded-2xl shadow-xl max-w-md w-full p-6">
              <h3 className="text-xl font-bold mb-2">{result.type === "win" ? "Tillykke!" : "Øv!"}</h3>
              <p className="text-gray-700">
                {result.type === "win"
                  ? `Du vandt: ${result.label}. Tjek din e‑mail for detaljer (eller vis koden på skærmen).`
                  : "Det blev desværre ikke til en præmie denne gang."}
              </p>
              <div className="mt-5 flex justify-end gap-3">
                <button
                  onClick={() => setResult(null)}
                  className="rounded-xl border border-gray-300 px-4 py-2 text-sm hover:bg-gray-50"
                >Luk</button>
              </div>
            </div>
          </div>
        )}

        <footer className="mt-10 text-xs text-gray-500">
          <p>
            Tip: Til produktion bør du forbinde formularen til et backend‑endpoint (f.eks. /api/signup) for at gemme deltagere, og registrere spins/resultater server‑side for at forhindre snyd.
          </p>
        </footer>
      </div>
    </div>
  );
}

Celebrate Fridays with Joy and Connection

Discover how FedFredag brings memorable Friday experiences that brighten your week and foster community spirit.

  • Share Your Favorite Friday Moments
  • Connect with Others Who Love Fridays
  • Find Inspiration for Weekend Plans
  • Create Lasting Traditions Every Week

Celebrate Memorable Fridays

Hear from our community as they share joyful moments and memorable Friday experiences with FedFredag.

FedFredag brings a fresh perspective to ending the week, turning Fridays into cherished memories for us all.

Maria Jensen

Creative Storyteller

Every Friday feels special thanks to the stories and events shared through FedFredag.

Ethan Brooks

Event Enthusiast

Celebrate Every Friday with Us

Discover moments that make Fridays unforgettable.

Joyful Stories

Sharing inspiring moments from memorable Fridays.

Community Vibes

Connecting people through shared Friday experiences.

Creative Highlights

Showcasing unique and fun Friday activities.

Exclusive Events

Bringing special Friday happenings to you.

Celebrate Every Friday Moment

Find quick answers to your questions about making your Fridays more joyful and memorable.

What kind of Friday experiences does FedFredag feature?

We showcase inspiring, fun, and unique Friday stories shared by our community.

How can I share my own Friday experience?

Simply submit your story through our platform to inspire others and join the celebration.

Is there a cost to access FedFredag content?

Access to our stories and features is completely free for all visitors.

Can I subscribe to receive Friday highlights?

Yes, sign up for our newsletter to get joyful Friday moments delivered to your inbox.

Celebrating the Joy of Every Friday

Explore our flexible plans designed to enhance your Friday experiences with unique perks.

Essential Access

$29.99

Unlock exclusive Friday content and community perks.

Memorable Moments Curated

Discover unique stories and events that make every Friday unforgettable.

Community Engagement

Connect with others who share the excitement of Friday celebrations.

Exclusive Content Access

Enjoy early access to special Friday features and joyful experiences.