import { useRef, useState, useCallback } from "react";
import { OKLCH_L, OKLCH_C } from "#shared/theme";

const COLOR_NAMES = [
  { name: "Candy Apple Red", hue: 0 },
  { name: "Boiling Magma", hue: 15 },
  { name: "Aerospace Orange", hue: 25 },
  { name: "Burtuqali Orange", hue: 33 },
  { name: "American Orange", hue: 40 },
  { name: "Cheese", hue: 48 },
  { name: "Amber", hue: 55 },
  { name: "Demonic Yellow", hue: 65 },
  { name: "Bat-Signal", hue: 72 },
  { name: "Bright Yellow Green", hue: 85 },
  { name: "Lasting Lime", hue: 95 },
  { name: "Bright Green", hue: 110 },
  { name: "Chlorophyll Green", hue: 120 },
  { name: "Green Screen", hue: 130 },
  { name: "Cathode Green", hue: 148 },
  { name: "Booger Buster", hue: 160 },
  { name: "Enthusiasm", hue: 170 },
  { name: "Ice Ice Baby", hue: 180 },
  { name: "Vivid Sky Blue", hue: 195 },
  { name: "Azure", hue: 214 },
  { name: "Blue Ribbon", hue: 225 },
  { name: "Icelandic Water", hue: 238 },
  { name: "Blue Pencil", hue: 250 },
  { name: "Electric Ultramarine", hue: 260 },
  { name: "Purple Climax", hue: 275 },
  { name: "Amethyst Ganzstar", hue: 285 },
  { name: "Electric Purple", hue: 295 },
  { name: "Phlox", hue: 305 },
  { name: "Brusque Pink", hue: 315 },
  { name: "Bright Magenta", hue: 325 },
  { name: "Pink", hue: 335 },
  { name: "Hot Flamingoes", hue: 345 },
  { name: "Carmine Red", hue: 355 },
];

function getColorName(hue: number): string {
  let best = COLOR_NAMES[0].name;
  let bestDist = 361;
  for (const c of COLOR_NAMES) {
    const d = Math.abs(c.hue - hue);
    const dist = Math.min(d, 360 - d);
    if (dist < bestDist) {
      bestDist = dist;
      best = c.name;
    }
  }
  return best;
}

function oklchToHex(l: number, c: number, h: number): string {
  const hRad = (h * Math.PI) / 180;
  const a = c * Math.cos(hRad);
  const b = c * Math.sin(hRad);

  const l_ = l + 0.3963377774 * a + 0.2158037573 * b;
  const m_ = l - 0.1055613458 * a - 0.0638541728 * b;
  const s_ = l - 0.0894841775 * a - 1.291485548 * b;

  const ll = l_ * l_ * l_;
  const mm = m_ * m_ * m_;
  const ss = s_ * s_ * s_;

  const toSrgb = (u: number) =>
    u <= 0.0031308 ? 12.92 * u : 1.055 * Math.pow(Math.max(0, u), 1 / 2.4) - 0.055;

  const r = toSrgb(+4.0767416621 * ll - 3.3077115913 * mm + 0.2309699292 * ss);
  const g = toSrgb(-1.2684380046 * ll + 2.6097574011 * mm - 0.3413193965 * ss);
  const bVal = toSrgb(-0.0041960863 * ll - 0.7034186147 * mm + 1.707614701 * ss);

  const clamp = (v: number) => Math.max(0, Math.min(255, Math.round(v * 255)));
  const hex = (v: number) => clamp(v).toString(16).padStart(2, "0");
  return `#${hex(r)}${hex(g)}${hex(bVal)}`;
}

interface HueSliderProps {
  hue: number;
  onChange: (hue: number) => void;
}

export function HueSlider({ hue, onChange }: HueSliderProps) {
  const sliderRef = useRef<HTMLDivElement>(null);
  const [dragging, setDragging] = useState(false);

  const hexColor = oklchToHex(OKLCH_L, OKLCH_C, hue);
  const colorName = getColorName(hue);

  const hueFromClientX = useCallback((clientX: number) => {
    const rect = sliderRef.current?.getBoundingClientRect();
    if (!rect) return hue;
    const x = Math.max(0, Math.min(clientX - rect.left, rect.width));
    return (x / rect.width) * 360;
  }, [hue]);

  const handlePointerDown = useCallback((e: React.PointerEvent) => {
    e.preventDefault();
    (e.target as HTMLElement).setPointerCapture(e.pointerId);
    setDragging(true);
    onChange(hueFromClientX(e.clientX));
  }, [hueFromClientX, onChange]);

  const handlePointerMove = useCallback((e: React.PointerEvent) => {
    if (!dragging) return;
    onChange(hueFromClientX(e.clientX));
  }, [dragging, hueFromClientX, onChange]);

  const handlePointerUp = useCallback(() => {
    setDragging(false);
  }, []);

  const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
    const step = e.shiftKey ? 10 : 2;
    if (e.key === "ArrowLeft") { e.preventDefault(); onChange(((hue - step) % 360 + 360) % 360); }
    if (e.key === "ArrowRight") { e.preventDefault(); onChange((hue + step) % 360); }
  }, [hue, onChange]);

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
        <div
          style={{
            width: 44,
            height: 44,
            borderRadius: 8,
            backgroundColor: hexColor,
            border: "1px solid var(--ed-border)",
            flexShrink: 0,
          }}
        />
        <div style={{ minWidth: 0 }}>
          <div style={{ fontWeight: 700, fontSize: "0.8rem", lineHeight: 1.3, color: "var(--ed-text)" }}>
            {colorName}
          </div>
          <div style={{ color: "var(--ed-text-secondary)", fontSize: "0.7rem", fontFamily: "monospace" }}>
            {hexColor.toUpperCase()} - {Math.round(hue)}&deg;
          </div>
        </div>
      </div>

      <div
        ref={sliderRef}
        role="slider"
        tabIndex={0}
        aria-label="Hue"
        aria-valuemin={0}
        aria-valuemax={360}
        aria-valuenow={Math.round(hue)}
        onPointerDown={handlePointerDown}
        onPointerMove={handlePointerMove}
        onPointerUp={handlePointerUp}
        onKeyDown={handleKeyDown}
        style={{
          position: "relative",
          height: 16,
          borderRadius: 10,
          border: "1px solid var(--ed-border)",
          background: "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)",
          cursor: "ew-resize",
          touchAction: "none",
        }}
      >
        <div
          style={{
            position: "absolute",
            top: "50%",
            left: `${(hue / 360) * 100}%`,
            width: 14,
            height: 14,
            borderRadius: "50%",
            border: "2px solid #fff",
            transform: "translate(-50%, -50%)",
            backgroundColor: hexColor,
            boxShadow: "0 0 0 1px rgba(0,0,0,0.15), 0 1px 3px rgba(0,0,0,0.3)",
            pointerEvents: "none",
          }}
        />
      </div>
    </div>
  );
}

export { oklchToHex };
