import { useState, useCallback, useEffect } from "react";
import { useNavigate, useLocation } from "react-router";
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
import {
  PersonStanding,
  Lock,
  Paintbrush,
  Bell,
  Shield,
  Eye,
  Key,
  Terminal,
  ExternalLink,
  XIcon,
} from "lucide-react";
import { cn } from "@/lib/utils";
import SettingsProfilePage from "@/page/settings/profile";
import SettingsSecurityPage from "@/page/settings/security";
import SettingsAppearancePage from "@/page/settings/appearance";
import SettingsNotificationsPage from "@/page/settings/notifications";
import SettingsPrivacyPage from "@/page/settings/privacy";
import SettingsAccessibilityPage from "@/page/settings/accessibility";
import SettingsTokensPage from "@/page/settings/tokens";
import SettingsSshKeysPage from "@/page/settings/ssh-keys";

type SectionKey =
  | "profile"
  | "security"
  | "appearance"
  | "notifications"
  | "privacy"
  | "accessibility"
  | "tokens"
  | "ssh-keys";

const NAV_SECTIONS = [
  {
    label: "Account",
    items: [
      { key: "profile" as SectionKey, icon: PersonStanding, label: "Profile" },
      { key: "security" as SectionKey, icon: Lock, label: "Security" },
    ],
  },
  {
    label: "Preferences",
    items: [
      { key: "appearance" as SectionKey, icon: Paintbrush, label: "Appearance" },
      { key: "notifications" as SectionKey, icon: Bell, label: "Notifications" },
      { key: "privacy" as SectionKey, icon: Shield, label: "Privacy" },
      { key: "accessibility" as SectionKey, icon: Eye, label: "Accessibility" },
    ],
  },
  {
    label: "Developer",
    items: [
      { key: "tokens" as SectionKey, icon: Key, label: "Access Tokens" },
      { key: "ssh-keys" as SectionKey, icon: Terminal, label: "SSH Keys" },
    ],
  },
];

const SECTIONS: Record<SectionKey, React.ComponentType> = {
  profile: SettingsProfilePage,
  security: SettingsSecurityPage,
  appearance: SettingsAppearancePage,
  notifications: SettingsNotificationsPage,
  privacy: SettingsPrivacyPage,
  accessibility: SettingsAccessibilityPage,
  tokens: SettingsTokensPage,
  "ssh-keys": SettingsSshKeysPage,
};

const SETTINGS_RETURN_PATH_KEY = "settings_return_path";

const sectionPath: Record<SectionKey, string> = {
  profile: "/settings/profile",
  security: "/settings/security",
  appearance: "/settings/appearance",
  notifications: "/settings/notifications",
  privacy: "/settings/privacy",
  accessibility: "/settings/accessibility",
  tokens: "/settings/tokens",
  "ssh-keys": "/settings/ssh-keys",
};

interface SettingsModalProps {
  open: boolean;
  onClose: () => void;
  initialSection?: string;
}

export function SettingsModal({ open, onClose, initialSection }: SettingsModalProps) {
  const [activeSection, setActiveSectionState] = useState<SectionKey>("profile");
  const [isExpanding, setIsExpanding] = useState(false);
  const navigate = useNavigate();
  const location = useLocation();

  // Sync initial section when modal opens
  useEffect(() => {
    if (open && initialSection && initialSection in SECTIONS) {
      setActiveSectionState(initialSection as SectionKey);
    }
  }, [open, initialSection]);

  const setActiveSection = (section: SectionKey) => {
    setActiveSectionState(section);
  };

  const handleOpenAsPage = useCallback(() => {
    localStorage.setItem(SETTINGS_RETURN_PATH_KEY, location.pathname);

    const el = document.querySelector('[data-slot="dialog-content"]') as HTMLDivElement | null;
    if (!el) return;

    const overlayEl = document.querySelector('[data-slot="dialog-overlay"]') as HTMLDivElement | null;

    setIsExpanding(true);

    const duration = 350;
    const start = performance.now();
    const startW = 80;
    const endW = 100;
    const startH = 85;
    const endH = 100;
    const startR = 12;
    const endR = 0;

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

    if (overlayEl) {
      overlayEl.animate(
        [{ opacity: 1 }, { opacity: 0 }],
        { duration: 300, easing: "ease", fill: "forwards" },
      );
    }

    const targetEl = el;
    function frame(now: number) {
      const elapsed = now - start;
      const progress = Math.min(elapsed / duration, 1);
      const eased = easeOutCubic(progress);

      const w = startW + (endW - startW) * eased;
      const h = startH + (endH - startH) * eased;
      const r = startR + (endR - startR) * eased;

      targetEl.style.setProperty("width", `${w}vw`, "important");
      targetEl.style.setProperty("height", `${h}vh`, "important");
      targetEl.style.setProperty("max-width", `${w}vw`, "important");
      targetEl.style.setProperty("max-height", `${h}vh`, "important");
      targetEl.style.setProperty("border-radius", `${r}px`, "important");

      if (progress < 1) {
        requestAnimationFrame(frame);
      } else {
        setIsExpanding(false);
        setTimeout(() => {
          onClose();
          navigate(sectionPath[activeSection]);
        }, 0);
      }
    }

    requestAnimationFrame(frame);
  }, [activeSection, onClose, navigate, location.pathname]);

  const ActiveComponent = SECTIONS[activeSection];

  return (
    <Dialog open={open} onOpenChange={(isOpen) => { if (!isOpen && !isExpanding) onClose(); }}>
      <DialogContent
        showCloseButton={false}
        className="!max-w-[80vw] !w-[80vw] !h-[85vh] !max-h-[85vh] !gap-0 !p-0 overflow-hidden !rounded-xl bg-sidebar"
      >
        <DialogTitle className="sr-only">Settings</DialogTitle>

        <div className="flex h-full w-full">
          {/* Sidebar */}
          <nav className="flex w-[218px] shrink-0 flex-col overflow-y-auto border-r border-border bg-sidebar/90">
            <div className="flex items-center justify-between px-4 pt-6 pb-4">
              <h2 className="text-[13px] font-semibold uppercase tracking-wider text-muted-foreground">
                Settings
              </h2>
            </div>

            {NAV_SECTIONS.map((section, si) => (
              <div key={si} className="mb-1">
                <div className="px-4 pt-4 pb-1 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">
                  {section.label}
                </div>
                {section.items.map((item) => (
                  <button
                    key={item.key}
                    onClick={() => setActiveSection(item.key)}
                    className={cn(
                      "flex w-full items-center gap-2.5 px-3 py-1.5 text-[14px] transition-colors text-left",
                      activeSection === item.key
                        ? "bg-accent text-foreground font-medium"
                        : "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
                    )}
                  >
                    <item.icon className="size-4 shrink-0" />
                    <span className="truncate">{item.label}</span>
                  </button>
                ))}
              </div>
            ))}
          </nav>

          {/* Content */}
          <div className="flex min-w-0 flex-1 flex-col bg-background">
            {/* Top bar */}
            <div className="flex shrink-0 items-center justify-end gap-2 h-12 border-b border-border px-4">
              <button
                onClick={handleOpenAsPage}
                disabled={isExpanding}
                className={cn(
                  "inline-flex items-center gap-1.5 rounded-lg border border-border px-3 h-7 text-[12px] font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
                  isExpanding && "opacity-50 cursor-not-allowed",
                )}
              >
                <ExternalLink className="size-3.5" />
                Open
              </button>
              <button
                onClick={onClose}
                disabled={isExpanding}
                className={cn(
                  "inline-flex items-center justify-center size-7 rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
                  isExpanding && "opacity-50 cursor-not-allowed",
                )}
              >
                <XIcon className="size-4" />
              </button>
            </div>

            {/* Scrollable content */}
            <div className="flex-1 overflow-y-auto overscroll-contain">
              <div className="mx-auto max-w-[660px] px-10 py-8">
                <ActiveComponent />
              </div>
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
