/**
 * TypographyPopover Component
 *
 * Cascading popover for typography settings.
 * Opens to the right of the main settings panel with a smooth animation.
 * Supports responsive values for fontSize, fontWeight, and letterSpacing.
 */

import { useState } from "react";
import { motion } from "motion/react";
import { Cross2Icon, DesktopIcon, LaptopIcon, MobileIcon } from "@radix-ui/react-icons";

import type { ResponsiveTypographySettings, Breakpoint, ResponsiveValue } from "@/types";
import { isResponsiveValue, createResponsiveValue } from "@/types";
import { FontSelect, Slider, ButtonGroup } from "../ui";
import { useGoogleFont } from "@/hooks/useGoogleFonts";

// Font weights
const FONT_WEIGHT_OPTIONS = [
  { value: "300", label: "Light" },
  { value: "400", label: "Regular" },
  { value: "500", label: "Medium" },
  { value: "600", label: "Semi" },
  { value: "700", label: "Bold" },
  { value: "800", label: "Extra" },
];

// Font style options
const FONT_STYLE_OPTIONS = [
  { value: "normal", label: "Normal" },
  { value: "italic", label: "Italic" },
];

// Text transform options
const TEXT_TRANSFORM_OPTIONS = [
  { value: "none", label: "Aa" },
  { value: "uppercase", label: "AA" },
  { value: "lowercase", label: "aa" },
  { value: "capitalize", label: "Aa" },
];

// Text decoration options
const TEXT_DECORATION_OPTIONS = [
  { value: "none", label: "None" },
  { value: "underline", label: "U̲" },
  { value: "line-through", label: "S̶" },
];

const popoverVariants = {
  hidden: {
    opacity: 0,
    scale: 0.95,
    x: -10,
  },
  visible: {
    opacity: 1,
    scale: 1,
    x: 0,
    transition: {
      type: "spring",
      stiffness: 400,
      damping: 30,
      delay: 0.05,
    },
  },
  exit: {
    opacity: 0,
    scale: 0.95,
    x: -10,
    transition: {
      duration: 0.1,
    },
  },
};

interface TypographyPopoverProps {
  typography: ResponsiveTypographySettings;
  onUpdate: (typography: ResponsiveTypographySettings) => void;
  onClose: () => void;
  /** Hide the text transform option (e.g., for decimal typography where it's not applicable) */
  hideTextTransform?: boolean;
}

export function TypographyPopover({ typography, onUpdate, onClose, hideTextTransform = false }: TypographyPopoverProps) {
  // Track active breakpoint for responsive fields
  const [activeBreakpoint, setActiveBreakpoint] = useState<Breakpoint>("desktop");

  // Load Google font when used
  useGoogleFont(typography.fontFamily);

  // Get current responsive values for active breakpoint
  const currentFontSize = isResponsiveValue(typography.fontSize) ? typography.fontSize[activeBreakpoint] : typography.fontSize;
  const currentFontWeight = isResponsiveValue(typography.fontWeight) ? typography.fontWeight[activeBreakpoint] : typography.fontWeight;
  const currentLetterSpacing = isResponsiveValue(typography.letterSpacing)
    ? typography.letterSpacing[activeBreakpoint]
    : typography.letterSpacing;

  // Handle change for non-responsive values
  const handleChange = <K extends keyof ResponsiveTypographySettings>(key: K, value: ResponsiveTypographySettings[K]) => {
    onUpdate({ ...typography, [key]: value });
  };

  // Handle change for responsive values
  const handleResponsiveChange = (key: "fontSize" | "fontWeight" | "letterSpacing", value: number) => {
    const currentValue = typography[key];
    const responsiveValue: ResponsiveValue<number> = isResponsiveValue(currentValue)
      ? { ...currentValue, [activeBreakpoint]: value }
      : createResponsiveValue(value);

    onUpdate({ ...typography, [key]: responsiveValue });
  };

  return (
    <motion.div
      className="floating-popover floating-popover--cascade"
      variants={popoverVariants}
      initial="hidden"
      animate="visible"
      exit="exit"
    >
      {/* Header */}
      <div className="floating-popover__header">
        <span className="floating-popover__title">Typography</span>
        <button className="floating-popover__close" onClick={onClose} aria-label="Close">
          <Cross2Icon className="w-3.5 h-3.5" />
        </button>
      </div>

      {/* Content */}
      <div className="floating-popover__content">
        {/* Font Family */}
        <div className="floating-popover__group">
          <label className="floating-popover__label">Font</label>
          <FontSelect value={typography.fontFamily} onValueChange={(value) => handleChange("fontFamily", value)} size="compact" />
        </div>

        {/* Font Size - Responsive */}
        <div className="floating-popover__group">
          <div className="floating-popover__responsive-header">
            <label className="floating-popover__label">Size: {currentFontSize}px</label>
            <div className="floating-popover__breakpoint-toggle">
              <button
                type="button"
                className={`floating-popover__breakpoint-btn ${activeBreakpoint === "desktop" ? "active" : ""}`}
                onClick={() => setActiveBreakpoint("desktop")}
                title="Desktop"
              >
                <DesktopIcon />
              </button>
              <button
                type="button"
                className={`floating-popover__breakpoint-btn ${activeBreakpoint === "tablet" ? "active" : ""}`}
                onClick={() => setActiveBreakpoint("tablet")}
                title="Tablet"
              >
                <LaptopIcon />
              </button>
              <button
                type="button"
                className={`floating-popover__breakpoint-btn ${activeBreakpoint === "mobile" ? "active" : ""}`}
                onClick={() => setActiveBreakpoint("mobile")}
                title="Mobile"
              >
                <MobileIcon />
              </button>
            </div>
          </div>
          <Slider
            value={currentFontSize}
            onValueChange={(value) => handleResponsiveChange("fontSize", value)}
            min={8}
            max={120}
            step={1}
            size="compact"
          />
        </div>

        {/* Font Weight - Responsive */}
        <div className="floating-popover__group">
          <div className="floating-popover__responsive-header">
            <label className="floating-popover__label">Weight</label>
            <div className="floating-popover__breakpoint-toggle">
              <button
                type="button"
                className={`floating-popover__breakpoint-btn ${activeBreakpoint === "desktop" ? "active" : ""}`}
                onClick={() => setActiveBreakpoint("desktop")}
                title="Desktop"
              >
                <DesktopIcon />
              </button>
              <button
                type="button"
                className={`floating-popover__breakpoint-btn ${activeBreakpoint === "tablet" ? "active" : ""}`}
                onClick={() => setActiveBreakpoint("tablet")}
                title="Tablet"
              >
                <LaptopIcon />
              </button>
              <button
                type="button"
                className={`floating-popover__breakpoint-btn ${activeBreakpoint === "mobile" ? "active" : ""}`}
                onClick={() => setActiveBreakpoint("mobile")}
                title="Mobile"
              >
                <MobileIcon />
              </button>
            </div>
          </div>
          <ButtonGroup
            options={FONT_WEIGHT_OPTIONS}
            value={String(currentFontWeight)}
            onChange={(value) => handleResponsiveChange("fontWeight", parseInt(value))}
            size="compact"
            fullWidth
          />
        </div>

        {/* Font Style */}
        <div className="floating-popover__group">
          <label className="floating-popover__label">Style</label>
          <ButtonGroup
            options={FONT_STYLE_OPTIONS}
            value={typography.fontStyle}
            onChange={(value) => handleChange("fontStyle", value as "normal" | "italic")}
            size="compact"
          />
        </div>

        {/* Line Height & Letter Spacing */}
        <div className="floating-popover__grid-2">
          <div className="floating-popover__group">
            <label className="floating-popover__label">Line Height: {typography.lineHeight.toFixed(1)}</label>
            <Slider
              value={typography.lineHeight}
              onValueChange={(value) => handleChange("lineHeight", value)}
              min={0.8}
              max={2.5}
              step={0.1}
              size="compact"
            />
          </div>

          {/* Letter Spacing - Responsive */}
          <div className="floating-popover__group">
            <div className="floating-popover__responsive-header floating-popover__responsive-header--compact">
              <label className="floating-popover__label">Spacing: {currentLetterSpacing}px</label>
              <div className="floating-popover__breakpoint-toggle floating-popover__breakpoint-toggle--sm">
                <button
                  type="button"
                  className={`floating-popover__breakpoint-btn ${activeBreakpoint === "desktop" ? "active" : ""}`}
                  onClick={() => setActiveBreakpoint("desktop")}
                  title="Desktop"
                >
                  <DesktopIcon />
                </button>
                <button
                  type="button"
                  className={`floating-popover__breakpoint-btn ${activeBreakpoint === "tablet" ? "active" : ""}`}
                  onClick={() => setActiveBreakpoint("tablet")}
                  title="Tablet"
                >
                  <LaptopIcon />
                </button>
                <button
                  type="button"
                  className={`floating-popover__breakpoint-btn ${activeBreakpoint === "mobile" ? "active" : ""}`}
                  onClick={() => setActiveBreakpoint("mobile")}
                  title="Mobile"
                >
                  <MobileIcon />
                </button>
              </div>
            </div>
            <Slider
              value={currentLetterSpacing}
              onValueChange={(value) => handleResponsiveChange("letterSpacing", value)}
              min={-2}
              max={10}
              step={0.5}
              size="compact"
            />
          </div>
        </div>

        {/* Text Transform - hidden for decimal typography */}
        {!hideTextTransform && (
          <div className="floating-popover__group">
            <label className="floating-popover__label">Transform</label>
            <ButtonGroup
              options={TEXT_TRANSFORM_OPTIONS}
              value={typography.textTransform}
              onChange={(value) => handleChange("textTransform", value as ResponsiveTypographySettings["textTransform"])}
              size="sm"
            />
          </div>
        )}

        {/* Text Decoration */}
        <div className="floating-popover__group">
          <label className="floating-popover__label">Decoration</label>
          <ButtonGroup
            options={TEXT_DECORATION_OPTIONS}
            value={typography.textDecoration}
            onChange={(value) => handleChange("textDecoration", value as ResponsiveTypographySettings["textDecoration"])}
            size="compact"
          />
        </div>
      </div>
    </motion.div>
  );
}

export default TypographyPopover;
