import { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import sparkHorse from "@/assets/spark-horse.png";

type Content = Record<string, unknown>;

export type ImpactLens = {
  id: number;
  label: string;
  emoji: string;
  hslVar: string;
  phase: string;
  description: string;
};

export type MirrorRing = {
  r: number;
  label: string;
  emoji: string;
  hslVar: string;
  desc: string;
};

const OUTER_R = 210;
const INNER_R = 65;
const CENTER = 310;

const defaultEyebrow = "The Impact Kaleidoscope";
const defaultTitle = "9 Lenses of Inquiry, Design & Impact";
const defaultHelper = "Click any lens to explore that stage of the PBEL journey.";
const defaultCenterImageAlt = "SPARK";
const defaultMirrorDetailEyebrow = "Cross-Cutting Overlay";
const defaultLensHoverHint = "Click to learn more";

const defaultLenses: ImpactLens[] = [
  {
    id: 1,
    label: "Launch",
    emoji: "🚀",
    hslVar: "--deep-sea",
    phase: "Context & Connection",
    description: "Hook curiosity — connect a global issue to students' lived reality and local community.",
  },
  {
    id: 2,
    label: "Essential Question",
    emoji: "❓",
    hslVar: "--deep-sea",
    phase: "Context & Connection",
    description: "Student ownership — draft 'How Might We…?' questions that frame the entire inquiry cycle.",
  },
  {
    id: 3,
    label: "Community Partners",
    emoji: "🤝",
    hslVar: "--mist",
    phase: "Context & Connection",
    description: "Authenticity & reciprocity — real community adoption ensures solutions leave the classroom.",
  },
  {
    id: 4,
    label: "Empathy & Investigation",
    emoji: "💛",
    hslVar: "--sunflower",
    phase: "Empathy & Insight",
    description: "Deeply understand users through interviews, observation, and baseline data. No 'solutioneering.'",
  },
  {
    id: 5,
    label: "POV & Define",
    emoji: "🎯",
    hslVar: "--sunflower",
    phase: "Empathy & Insight",
    description: "Synthesize insights into a clear point of view. Define measurable targets for impact.",
  },
  {
    id: 6,
    label: "Core + Enrichment",
    emoji: "📚",
    hslVar: "--moss",
    phase: "Empathy & Insight",
    description: "Just-in-time learning — Math, Science, ELA, and AI skills unlock solutions students actually need.",
  },
  {
    id: 7,
    label: "Product",
    emoji: "🔧",
    hslVar: "--valencia",
    phase: "Action & Impact",
    description: "Ideate → Prototype. Low-fidelity sketches evolve into testable models and builds.",
  },
  {
    id: 8,
    label: "Critique & Revision",
    emoji: "🔄",
    hslVar: "--valencia",
    phase: "Action & Impact",
    description: "Test with real users. Iterate based on data, peer critique, and expert feedback.",
  },
  {
    id: 9,
    label: "Exhibition",
    emoji: "🎤",
    hslVar: "--salmon",
    phase: "Action & Impact",
    description: "Storytelling for influence — pilot, implement, and present at the Innovation & Impact Showcase.",
  },
];

const defaultMirrorRings: MirrorRing[] = [
  {
    r: OUTER_R + 28,
    label: "Student Voice & Choice",
    emoji: "🗣️",
    hslVar: "--moss",
    desc: "Learners co-design the inquiry, choose roles, and shape deliverables at every stage.",
  },
  {
    r: OUTER_R + 52,
    label: "Service Learning (IPARDE)",
    emoji: "🔁",
    hslVar: "--deep-sea",
    desc: "Investigate, Prepare, Action, Reflect, Demonstrate, Evaluate — runs beneath every lens.",
  },
  {
    r: OUTER_R + 76,
    label: "Safety, Ethics & Equity",
    emoji: "🛡️",
    hslVar: "--valencia",
    desc: "Age-appropriate tools, consent protocols, equitable access, and ethical design thinking.",
  },
];

function str(c: unknown): string {
  return typeof c === "string" ? c : "";
}

function normalizeHslVar(raw: string, fallback: string): string {
  const v = raw.trim() || fallback;
  if (v.startsWith("--")) return v;
  return `--${v.replace(/^-+/, "")}`;
}

function parseLenses(content: Content | undefined): ImpactLens[] {
  const raw = content?.lenses;
  if (!Array.isArray(raw) || raw.length === 0) return defaultLenses;
  const parsed = raw
    .filter((x): x is Record<string, unknown> => x != null && typeof x === "object")
    .map((o, i) => {
      const idNum = typeof o.id === "number" ? o.id : Number(o.id);
      return {
        id: Number.isFinite(idNum) ? idNum : i + 1,
        label: str(o.label).trim() || `Lens ${i + 1}`,
        emoji: str(o.emoji).trim() || "•",
        hslVar: normalizeHslVar(str(o.hslVar), "--deep-sea"),
        phase: str(o.phase).trim() || "",
        description: str(o.description).trim() || "",
      };
    });
  return parsed.length === 0 ? defaultLenses : parsed;
}

function parseMirrorRings(content: Content | undefined): MirrorRing[] {
  const raw = content?.mirrorRings;
  if (!Array.isArray(raw) || raw.length === 0) return defaultMirrorRings;
  const fallbackR = [OUTER_R + 28, OUTER_R + 52, OUTER_R + 76];
  const parsed = raw
    .filter((x): x is Record<string, unknown> => x != null && typeof x === "object")
    .map((o, i) => {
      const rNum = typeof o.r === "number" ? o.r : Number(o.r);
      return {
        r: Number.isFinite(rNum) ? rNum : (fallbackR[i] ?? OUTER_R + 28 + i * 24),
        label: str(o.label).trim() || `Mirror ${i + 1}`,
        emoji: str(o.emoji).trim() || "•",
        hslVar: normalizeHslVar(str(o.hslVar), "--moss"),
        desc: str(o.desc).trim() || "",
      };
    });
  return parsed.length === 0 ? defaultMirrorRings : parsed;
}

function polarToXY(cx: number, cy: number, r: number, angleDeg: number) {
  const rad = ((angleDeg - 90) * Math.PI) / 180;
  return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };
}

function slicePath(index: number, anglePerSlice: number) {
  const startAngle = index * anglePerSlice;
  const endAngle = startAngle + anglePerSlice;
  const outerStart = polarToXY(CENTER, CENTER, OUTER_R, startAngle);
  const outerEnd = polarToXY(CENTER, CENTER, OUTER_R, endAngle);
  const innerEnd = polarToXY(CENTER, CENTER, INNER_R, endAngle);
  const innerStart = polarToXY(CENTER, CENTER, INNER_R, startAngle);
  return [
    `M ${outerStart.x} ${outerStart.y}`,
    `A ${OUTER_R} ${OUTER_R} 0 0 1 ${outerEnd.x} ${outerEnd.y}`,
    `L ${innerEnd.x} ${innerEnd.y}`,
    `A ${INNER_R} ${INNER_R} 0 0 0 ${innerStart.x} ${innerStart.y}`,
    `Z`,
  ].join(" ");
}

function labelPosition(index: number, anglePerSlice: number) {
  const midAngle = index * anglePerSlice + anglePerSlice / 2;
  const labelR = (OUTER_R + INNER_R) / 2 + 10;
  return { ...polarToXY(CENTER, CENTER, labelR, midAngle), angle: midAngle };
}

export function ImpactKaleidoscopeBlock({ content }: { content?: Content }) {
  const eyebrow = str(content?.eyebrow).trim() || defaultEyebrow;
  const title = str(content?.title).trim() || defaultTitle;
  const helper = str(content?.helper).trim() || defaultHelper;
  const centerImageAlt = str(content?.centerImageAlt).trim() || defaultCenterImageAlt;
  const mirrorDetailEyebrow = str(content?.mirrorDetailEyebrow).trim() || defaultMirrorDetailEyebrow;
  const lensHoverHint = str(content?.lensHoverHint).trim() || defaultLensHoverHint;

  const lenses = parseLenses(content);
  const mirrorRings = parseMirrorRings(content);

  const SLICES = Math.max(lenses.length, 1);
  const ANGLE_PER_SLICE = 360 / SLICES;

  const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
  const [selectedLens, setSelectedLens] = useState<ImpactLens | null>(null);
  const [selectedMirror, setSelectedMirror] = useState<MirrorRing | null>(null);
  const [hoveredMirror, setHoveredMirror] = useState<number | null>(null);

  return (
    <section className="py-16 md:py-24 bg-background relative overflow-hidden">
      <div className="absolute inset-0 pointer-events-none">
        <div className="absolute left-1/2 top-[320px] -translate-x-1/2 -translate-y-1/2 w-[700px] h-[700px] rounded-full bg-[radial-gradient(circle,hsl(var(--valencia)/0.04)_0%,transparent_70%)]" />
      </div>

      <div className="container mx-auto px-6 relative z-10">
        <motion.div
          className="text-center mb-14"
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.3 }}
        >
          <p className="font-display text-xs tracking-[0.2em] uppercase text-valencia mb-2">{eyebrow}</p>
          <h2 className="font-display text-2xl md:text-3xl font-bold text-foreground">{title}</h2>
          <p className="text-muted-foreground mt-2 text-sm max-w-md mx-auto">{helper}</p>
        </motion.div>

        {/* Desktop Kaleidoscope */}
        <div className="hidden md:flex justify-center items-center">
          <div className="relative" style={{ width: CENTER * 2, height: CENTER * 2, maxWidth: "100%" }}>
            <motion.svg
              viewBox={`0 0 ${CENTER * 2} ${CENTER * 2}`}
              className="w-full h-full"
              initial={{ opacity: 0, rotate: -20, scale: 0.85 }}
              animate={{ opacity: 1, rotate: 0, scale: 1 }}
              transition={{ duration: 0.8, ease: "easeOut" }}
            >
              {mirrorRings.map((ring, ri) => (
                <g key={`${ring.label}-${ri}`} className="cursor-pointer" onClick={() => setSelectedMirror(ring)}>
                  <motion.circle
                    cx={CENTER}
                    cy={CENTER}
                    r={ring.r}
                    fill="none"
                    stroke={`hsl(var(${ring.hslVar}))`}
                    strokeWidth={hoveredMirror === ri ? 18 : 14}
                    strokeOpacity={hoveredMirror === ri ? 0.5 : 0.18}
                    strokeDasharray={`${2 * Math.PI * ring.r * 0.08} ${2 * Math.PI * ring.r * 0.025}`}
                    initial={{ rotate: 0 }}
                    animate={{ rotate: ri % 2 === 0 ? 360 : -360 }}
                    transition={{ duration: 40 + ri * 15, repeat: Infinity, ease: "linear" }}
                    style={{ transformOrigin: `${CENTER}px ${CENTER}px` }}
                    onHoverStart={() => setHoveredMirror(ri)}
                    onHoverEnd={() => setHoveredMirror(null)}
                  />
                  {[0, 120, 240].map((angleDeg) => {
                    const pos = polarToXY(CENTER, CENTER, ring.r, angleDeg + ri * 40);
                    return (
                      <g key={angleDeg}>
                        <circle
                          cx={pos.x}
                          cy={pos.y}
                          r={10}
                          fill={`hsl(var(${ring.hslVar}))`}
                          opacity={hoveredMirror === ri ? 0.9 : 0.5}
                          className="pointer-events-none"
                        />
                        <text
                          x={pos.x}
                          y={pos.y}
                          textAnchor="middle"
                          dominantBaseline="middle"
                          fontSize={10}
                          className="pointer-events-none"
                        >
                          {ring.emoji}
                        </text>
                      </g>
                    );
                  })}
                </g>
              ))}

              <circle cx={CENTER} cy={CENTER} r={OUTER_R + 6} fill="none" stroke="hsl(var(--card))" strokeWidth={10} />

              {lenses.map((lens, i) => {
                const path = slicePath(i, ANGLE_PER_SLICE);
                const lbl = labelPosition(i, ANGLE_PER_SLICE);
                let textAngle = lbl.angle - 90;
                if (lbl.angle > 90 && lbl.angle < 270) textAngle += 180;

                return (
                  <g key={lens.id} className="cursor-pointer" onClick={() => setSelectedLens(lens)}>
                    <motion.path
                      d={path}
                      fill={`hsl(var(${lens.hslVar}))`}
                      stroke="hsl(var(--card))"
                      strokeWidth={3}
                      initial={{ opacity: 0, scale: 0.8 }}
                      animate={{
                        opacity: 1,
                        scale: hoveredIndex === i ? 1.04 : 1,
                      }}
                      whileHover={{ scale: 1.06 }}
                      transition={{ delay: 0.06 * i + 0.2, duration: 0.4 }}
                      onHoverStart={() => setHoveredIndex(i)}
                      onHoverEnd={() => setHoveredIndex(null)}
                      style={{ transformOrigin: `${CENTER}px ${CENTER}px` }}
                    />
                    <text
                      x={lbl.x}
                      y={lbl.y}
                      textAnchor="middle"
                      dominantBaseline="middle"
                      transform={`rotate(${textAngle}, ${lbl.x}, ${lbl.y})`}
                      className="pointer-events-none select-none"
                      fill="white"
                      fontSize={11}
                      fontWeight={700}
                      fontFamily="Outfit, sans-serif"
                      letterSpacing="0.04em"
                    >
                      {lens.label}
                    </text>
                    <text
                      x={polarToXY(CENTER, CENTER, (OUTER_R + INNER_R) / 2 - 18, i * ANGLE_PER_SLICE + ANGLE_PER_SLICE / 2).x}
                      y={polarToXY(CENTER, CENTER, (OUTER_R + INNER_R) / 2 - 18, i * ANGLE_PER_SLICE + ANGLE_PER_SLICE / 2).y}
                      textAnchor="middle"
                      dominantBaseline="middle"
                      className="pointer-events-none"
                      fontSize={18}
                    >
                      {lens.emoji}
                    </text>
                  </g>
                );
              })}

              <circle cx={CENTER} cy={CENTER} r={INNER_R} fill="hsl(var(--card))" stroke="hsl(var(--border))" strokeWidth={2} />
              <foreignObject
                x={CENTER - INNER_R + 5}
                y={CENTER - INNER_R + 5}
                width={(INNER_R - 5) * 2}
                height={(INNER_R - 5) * 2}
              >
                <div className="w-full h-full flex items-center justify-center">
                  <img src={sparkHorse} alt={centerImageAlt} className="w-full h-full object-contain drop-shadow-lg" />
                </div>
              </foreignObject>
            </motion.svg>

            <AnimatePresence>
              {hoveredIndex !== null && lenses[hoveredIndex] && (
                <motion.div
                  className="absolute left-1/2 -translate-x-1/2 bg-card border border-border rounded-xl shadow-xl p-4 max-w-xs text-center pointer-events-none z-30"
                  style={{ top: CENTER * 2 + 16 }}
                  initial={{ opacity: 0, y: -8 }}
                  animate={{ opacity: 1, y: 0 }}
                  exit={{ opacity: 0, y: -8 }}
                  transition={{ duration: 0.15 }}
                >
                  <div className="flex items-center justify-center gap-2 mb-1">
                    <span className="text-lg">{lenses[hoveredIndex].emoji}</span>
                    <span className="font-display text-sm font-bold text-foreground">
                      Lens {lenses[hoveredIndex].id}: {lenses[hoveredIndex].label}
                    </span>
                  </div>
                  <p className="text-muted-foreground text-xs">{lenses[hoveredIndex].description}</p>
                  <p className="text-[10px] text-primary mt-1 font-display font-semibold">
                    {lenses[hoveredIndex].phase}
                  </p>
                </motion.div>
              )}
            </AnimatePresence>

            <AnimatePresence>
              {hoveredMirror !== null && mirrorRings[hoveredMirror] && (
                <motion.div
                  className="absolute left-1/2 -translate-x-1/2 bg-card border border-border rounded-xl shadow-xl p-3 max-w-xs text-center pointer-events-none z-30"
                  style={{ top: -60 }}
                  initial={{ opacity: 0, y: 8 }}
                  animate={{ opacity: 1, y: 0 }}
                  exit={{ opacity: 0, y: 8 }}
                  transition={{ duration: 0.15 }}
                >
                  <div className="flex items-center justify-center gap-2 mb-1">
                    <span className="text-lg">{mirrorRings[hoveredMirror].emoji}</span>
                    <span className="font-display text-xs font-bold text-foreground">
                      {mirrorRings[hoveredMirror].label}
                    </span>
                  </div>
                  <p className="text-muted-foreground text-[10px]">{lensHoverHint}</p>
                </motion.div>
              )}
            </AnimatePresence>
          </div>
        </div>

        {/* Mobile Kaleidoscope */}
        <div className="md:hidden flex flex-col items-center">
          <div className="relative" style={{ width: 300, height: 300 }}>
            <svg viewBox={`0 0 ${CENTER * 2} ${CENTER * 2}`} className="w-full h-full">
              <circle cx={CENTER} cy={CENTER} r={OUTER_R + 6} fill="none" stroke="hsl(var(--card))" strokeWidth={12} />
              {lenses.map((lens, i) => {
                const path = slicePath(i, ANGLE_PER_SLICE);
                const emojiPos = polarToXY(
                  CENTER,
                  CENTER,
                  (OUTER_R + INNER_R) / 2,
                  i * ANGLE_PER_SLICE + ANGLE_PER_SLICE / 2
                );
                return (
                  <g key={lens.id} onClick={() => setSelectedLens(lens)} className="cursor-pointer">
                    <path d={path} fill={`hsl(var(${lens.hslVar}))`} stroke="hsl(var(--card))" strokeWidth={3} />
                    <text x={emojiPos.x} y={emojiPos.y} textAnchor="middle" dominantBaseline="middle" fontSize={16}>
                      {lens.emoji}
                    </text>
                  </g>
                );
              })}
              <circle cx={CENTER} cy={CENTER} r={INNER_R} fill="hsl(var(--card))" stroke="hsl(var(--border))" strokeWidth={2} />
              <foreignObject
                x={CENTER - INNER_R + 5}
                y={CENTER - INNER_R + 5}
                width={(INNER_R - 5) * 2}
                height={(INNER_R - 5) * 2}
              >
                <div className="w-full h-full flex items-center justify-center">
                  <img src={sparkHorse} alt={centerImageAlt} className="w-full h-full object-contain drop-shadow-lg" />
                </div>
              </foreignObject>
            </svg>
          </div>
        </div>

        <AnimatePresence>
          {selectedLens && (
            <motion.div
              className="max-w-2xl mx-auto mt-8 bg-card border-2 rounded-xl p-6 relative"
              style={{ borderColor: `hsl(var(${selectedLens.hslVar}))` }}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: 20 }}
              key={selectedLens.id}
            >
              <button
                type="button"
                onClick={() => setSelectedLens(null)}
                className="absolute top-3 right-3 text-muted-foreground hover:text-foreground text-lg"
              >
                ✕
              </button>
              <div className="flex items-center gap-3 mb-3">
                <span className="text-3xl">{selectedLens.emoji}</span>
                <div>
                  <p className="text-[10px] uppercase tracking-widest text-muted-foreground font-display">
                    {selectedLens.phase}
                  </p>
                  <h3 className="font-display text-xl font-bold text-foreground">
                    Lens {selectedLens.id}: {selectedLens.label}
                  </h3>
                </div>
              </div>
              <p className="text-muted-foreground text-sm leading-relaxed">{selectedLens.description}</p>
            </motion.div>
          )}
        </AnimatePresence>

        <AnimatePresence>
          {selectedMirror && (
            <motion.div
              className="max-w-2xl mx-auto mt-4 bg-card border-2 rounded-xl p-6 relative"
              style={{ borderColor: `hsl(var(${selectedMirror.hslVar}))` }}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: 20 }}
              key={selectedMirror.label}
            >
              <button
                type="button"
                onClick={() => setSelectedMirror(null)}
                className="absolute top-3 right-3 text-muted-foreground hover:text-foreground text-lg"
              >
                ✕
              </button>
              <div className="flex items-center gap-3 mb-3">
                <span className="text-3xl">{selectedMirror.emoji}</span>
                <div>
                  <p className="text-[10px] uppercase tracking-widest text-muted-foreground font-display">
                    {mirrorDetailEyebrow}
                  </p>
                  <h3 className="font-display text-xl font-bold text-foreground">{selectedMirror.label}</h3>
                </div>
              </div>
              <p className="text-muted-foreground text-sm leading-relaxed">{selectedMirror.desc}</p>
            </motion.div>
          )}
        </AnimatePresence>
      </div>
    </section>
  );
}
