import { useState, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { springs, microInteraction } from "@/lib/motion";
import {
  Sun, Moon, Monitor, RotateCcw,
} from "lucide-react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog";
import { Separator } from "@/components/ui/separator";
import { Button } from "@/components/ui/button";
import { useAppStore } from "@/stores/app-store";
import type { AppSettings } from "@/types/settings";
import type { ColumnWidth } from "@/types/board";

interface SettingsDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

type Tab = "appearance" | "boards" | "shortcuts" | "about";

const THEME_OPTIONS: {
  value: AppSettings["theme"];
  label: string;
  icon: typeof Sun;
}[] = [
  { value: "light", label: "Light", icon: Sun },
  { value: "dark", label: "Dark", icon: Moon },
  { value: "system", label: "System", icon: Monitor },
];

const ACCENT_PRESETS: { hue: string; label: string }[] = [
  { hue: "160", label: "Teal" },
  { hue: "240", label: "Blue" },
  { hue: "300", label: "Purple" },
  { hue: "350", label: "Pink" },
  { hue: "25", label: "Red" },
  { hue: "55", label: "Orange" },
  { hue: "85", label: "Yellow" },
  { hue: "130", label: "Lime" },
  { hue: "200", label: "Cyan" },
  { hue: "0", label: "Slate" },
];

const DENSITY_OPTIONS: {
  value: AppSettings["density"];
  label: string;
}[] = [
  { value: "compact", label: "Compact" },
  { value: "comfortable", label: "Comfortable" },
  { value: "spacious", label: "Spacious" },
];

const WIDTH_OPTIONS: { value: ColumnWidth; label: string }[] = [
  { value: "narrow", label: "Narrow" },
  { value: "standard", label: "Standard" },
  { value: "wide", label: "Wide" },
];

const SHORTCUTS: { key: string; description: string; category: string }[] = [
  { key: "Ctrl+K", description: "Open command palette", category: "Navigation" },
  { key: "Ctrl+Z", description: "Undo", category: "Board" },
  { key: "Ctrl+Shift+Z", description: "Redo", category: "Board" },
  { key: "?", description: "Keyboard shortcuts", category: "Navigation" },
  { key: "Escape", description: "Close modal / cancel", category: "Navigation" },
];

const TABS: { value: Tab; label: string }[] = [
  { value: "appearance", label: "Appearance" },
  { value: "boards", label: "Boards" },
  { value: "shortcuts", label: "Shortcuts" },
  { value: "about", label: "About" },
];

function SectionLabel({ children }: { children: React.ReactNode }) {
  return (
    <label className="mb-2 block font-mono text-xs font-semibold uppercase tracking-widest text-pylon-text-secondary">
      {children}
    </label>
  );
}

export function SettingsDialog({ open, onOpenChange }: SettingsDialogProps) {
  const [tab, setTab] = useState<Tab>("appearance");
  const settings = useAppStore((s) => s.settings);
  const setTheme = useAppStore((s) => s.setTheme);
  const setAccentColor = useAppStore((s) => s.setAccentColor);
  const setUiZoom = useAppStore((s) => s.setUiZoom);
  const setDensity = useAppStore((s) => s.setDensity);
  const setDefaultColumnWidth = useAppStore((s) => s.setDefaultColumnWidth);

  const roRef = useRef<ResizeObserver | null>(null);
  const [height, setHeight] = useState<number | "auto">("auto");

  // Callback ref: sets up ResizeObserver when dialog content mounts in portal
  const contentRef = useCallback((node: HTMLDivElement | null) => {
    if (roRef.current) {
      roRef.current.disconnect();
      roRef.current = null;
    }
    if (node) {
      const measure = () => setHeight(node.getBoundingClientRect().height);
      measure();
      roRef.current = new ResizeObserver(measure);
      roRef.current.observe(node);
    }
  }, []);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="bg-pylon-surface sm:max-w-lg overflow-hidden p-0">
        <motion.div
          animate={{ height: typeof height === "number" && height > 0 ? height : "auto" }}
          initial={false}
          transition={{ type: "spring", stiffness: 500, damping: 30 }}
          className="overflow-hidden"
        >
          <div ref={contentRef} className="flex flex-col gap-4 p-6">
            <DialogHeader>
              <DialogTitle className="font-heading text-pylon-text">
                Settings
              </DialogTitle>
              <DialogDescription className="text-pylon-text-secondary">
                Configure your OpenPylon preferences.
              </DialogDescription>
            </DialogHeader>

            {/* Tab bar */}
            <div className="flex gap-1 border-b border-border pb-2">
              {TABS.map((t) => (
                <Button
                  key={t.value}
                  variant={tab === t.value ? "secondary" : "ghost"}
                  size="sm"
                  onClick={() => setTab(t.value)}
                  className="font-mono text-xs"
                >
                  {t.label}
                </Button>
              ))}
            </div>

            {/* Tab content — entire dialog height animates between tabs */}
            <AnimatePresence mode="popLayout" initial={false}>
              <motion.div
                key={tab}
                className="flex flex-col gap-5"
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                exit={{ opacity: 0 }}
                transition={{ duration: 0.15 }}
              >
              {tab === "appearance" && (
            <>
              {/* Theme */}
              <div>
                <SectionLabel>Theme</SectionLabel>
                <div className="flex gap-2">
                  {THEME_OPTIONS.map(({ value, label, icon: Icon }) => (
                    <Button
                      key={value}
                      type="button"
                      variant={settings.theme === value ? "default" : "outline"}
                      size="sm"
                      onClick={() => setTheme(value)}
                      className="flex-1 gap-2"
                    >
                      <Icon className="size-4" />
                      {label}
                    </Button>
                  ))}
                </div>
              </div>

              <Separator />

              {/* UI Zoom */}
              <div>
                <div className="mb-2 flex items-center justify-between">
                  <SectionLabel>UI Zoom</SectionLabel>
                  <div className="flex items-center gap-2">
                    <span className="font-mono text-xs text-pylon-text-secondary">
                      {Math.round(settings.uiZoom * 100)}%
                    </span>
                    {settings.uiZoom !== 1 && (
                      <Button
                        variant="ghost"
                        size="icon-xs"
                        onClick={() => setUiZoom(1)}
                        className="text-pylon-text-secondary hover:text-pylon-text"
                      >
                        <RotateCcw className="size-3" />
                      </Button>
                    )}
                  </div>
                </div>
                <input
                  type="range"
                  min="0.75"
                  max="1.5"
                  step="0.05"
                  value={settings.uiZoom}
                  onChange={(e) => setUiZoom(parseFloat(e.target.value))}
                  className="w-full accent-pylon-accent"
                />
                <div className="mt-1 flex justify-between font-mono text-[10px] text-pylon-text-secondary">
                  <span>75%</span>
                  <span>100%</span>
                  <span>150%</span>
                </div>
              </div>

              <Separator />

              {/* Accent Color */}
              <div>
                <SectionLabel>Accent Color</SectionLabel>
                <div className="flex flex-wrap gap-2">
                  {ACCENT_PRESETS.map(({ hue, label }) => {
                    const isAchromatic = hue === "0";
                    const bg = isAchromatic
                      ? "oklch(50% 0 0)"
                      : `oklch(55% 0.12 ${hue})`;
                    return (
                      <motion.button
                        key={hue}
                        type="button"
                        onClick={() => setAccentColor(hue)}
                        className="size-7 rounded-full"
                        style={{
                          backgroundColor: bg,
                          outline: settings.accentColor === hue ? "2px solid currentColor" : "none",
                          outlineOffset: "2px",
                        }}
                        whileHover={microInteraction.hover}
                        whileTap={microInteraction.tap}
                        transition={springs.snappy}
                        aria-label={label}
                        title={label}
                      />
                    );
                  })}
                </div>
              </div>

              <Separator />

              {/* Density */}
              <div>
                <SectionLabel>Density</SectionLabel>
                <div className="flex gap-2">
                  {DENSITY_OPTIONS.map(({ value, label }) => (
                    <Button
                      key={value}
                      type="button"
                      variant={settings.density === value ? "default" : "outline"}
                      size="sm"
                      onClick={() => setDensity(value)}
                      className="flex-1"
                    >
                      {label}
                    </Button>
                  ))}
                </div>
              </div>
            </>
          )}

          {tab === "boards" && (
            <div>
              <SectionLabel>Default Column Width</SectionLabel>
              <div className="flex gap-2">
                {WIDTH_OPTIONS.map(({ value, label }) => (
                  <Button
                    key={value}
                    type="button"
                    variant={settings.defaultColumnWidth === value ? "default" : "outline"}
                    size="sm"
                    onClick={() => setDefaultColumnWidth(value)}
                    className="flex-1"
                  >
                    {label}
                  </Button>
                ))}
              </div>
            </div>
          )}

          {tab === "shortcuts" && (
            <div className="flex flex-col gap-1">
              {SHORTCUTS.map(({ key, description }) => (
                <div key={key} className="flex items-center justify-between py-1">
                  <span className="text-sm text-pylon-text">{description}</span>
                  <kbd className="rounded bg-pylon-column px-2 py-0.5 font-mono text-xs text-pylon-text-secondary">
                    {key}
                  </kbd>
                </div>
              ))}
            </div>
          )}

          {tab === "about" && (
            <div className="space-y-2 text-sm text-pylon-text">
              <p className="font-heading text-lg">OpenPylon</p>
              <p className="text-pylon-text-secondary">
                v0.1.0 &middot; Local-first Kanban board
              </p>
              <p className="text-pylon-text-secondary">
                Built with Tauri, React, and TypeScript.
              </p>
            </div>
          )}
              </motion.div>
            </AnimatePresence>
          </div>
        </motion.div>
      </DialogContent>
    </Dialog>
  );
}
