/**
 * TypographyModal Component
 *
 * Modal for editing typography settings including font family, size,
 * weight, style, line-height, letter-spacing, text-transform, and text-decoration.
 *
 * Supports both responsive (desktop/tablet/mobile) and non-responsive modes.
 */

import { useState } from "react";
import * as Dialog from "@radix-ui/react-dialog";
import { Cross2Icon, DesktopIcon, LaptopIcon, MobileIcon } from "@radix-ui/react-icons";

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

// Font weights
const FONT_WEIGHT_OPTIONS = [
  { value: "100", label: "Thin (100)" },
  { value: "200", label: "Extra Light (200)" },
  { value: "300", label: "Light (300)" },
  { value: "400", label: "Normal (400)" },
  { value: "500", label: "Medium (500)" },
  { value: "600", label: "Semi Bold (600)" },
  { value: "700", label: "Bold (700)" },
  { value: "800", label: "Extra Bold (800)" },
  { value: "900", label: "Black (900)" },
];

// 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: "None" },
  { value: "uppercase", label: "Uppercase" },
  { value: "lowercase", label: "Lowercase" },
  { value: "capitalize", label: "Capitalize" },
];

// Text decoration options
const TEXT_DECORATION_OPTIONS = [
  { value: "none", label: "None" },
  { value: "underline", label: "Underline" },
  { value: "line-through", label: "Strikethrough" },
];

// Breakpoint options
const BREAKPOINTS: { value: Breakpoint; icon: React.ReactNode; label: string }[] = [
  { value: "desktop", icon: <DesktopIcon />, label: "Desktop" },
  { value: "tablet", icon: <LaptopIcon />, label: "Tablet" },
  { value: "mobile", icon: <MobileIcon />, label: "Mobile" },
];

// Helper to convert responsive to non-responsive
const toNonResponsive = (responsive: ResponsiveTypographySettings): TypographySettings => ({
  fontFamily: responsive.fontFamily,
  fontSize: responsive.fontSize.desktop,
  fontWeight: responsive.fontWeight.desktop,
  fontStyle: responsive.fontStyle,
  lineHeight: responsive.lineHeight,
  letterSpacing: responsive.letterSpacing.desktop,
  textTransform: responsive.textTransform,
  textDecoration: responsive.textDecoration,
});

// Helper to convert non-responsive to responsive
const toResponsive = (nonResponsive: TypographySettings, original?: ResponsiveTypographySettings): ResponsiveTypographySettings => ({
  fontFamily: nonResponsive.fontFamily,
  fontSize: original ? { ...original.fontSize, desktop: nonResponsive.fontSize } : createResponsiveValue(nonResponsive.fontSize),
  fontWeight: original ? { ...original.fontWeight, desktop: nonResponsive.fontWeight } : createResponsiveValue(nonResponsive.fontWeight),
  fontStyle: nonResponsive.fontStyle,
  lineHeight: nonResponsive.lineHeight,
  letterSpacing: original
    ? { ...original.letterSpacing, desktop: nonResponsive.letterSpacing }
    : createResponsiveValue(nonResponsive.letterSpacing),
  textTransform: nonResponsive.textTransform,
  textDecoration: nonResponsive.textDecoration,
});

// Props supporting both responsive and non-responsive modes
interface TypographyModalPropsBase {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

interface TypographyModalPropsResponsive extends TypographyModalPropsBase {
  typography: ResponsiveTypographySettings;
  onUpdate: (typography: ResponsiveTypographySettings) => void;
  isResponsive: true;
}

interface TypographyModalPropsNonResponsive extends TypographyModalPropsBase {
  typography: TypographySettings;
  onUpdate: (typography: TypographySettings) => void;
  isResponsive?: false;
}

type TypographyModalProps = TypographyModalPropsResponsive | TypographyModalPropsNonResponsive;

export function TypographyModal(props: TypographyModalProps) {
  const { open, onOpenChange } = props;
  const [activeBreakpoint, setActiveBreakpoint] = useState<Breakpoint>("desktop");

  // Normalize to responsive format internally
  const isResponsive = props.isResponsive === true;
  const responsiveTypography: ResponsiveTypographySettings = isResponsive
    ? (props.typography as ResponsiveTypographySettings)
    : toResponsive(props.typography as TypographySettings);

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

  // Get values for current breakpoint
  const getValue = <T,>(responsiveValue: ResponsiveValue<T>): T => responsiveValue[activeBreakpoint];

  // Handle responsive field change
  const handleResponsiveChange = <T,>(field: "fontSize" | "fontWeight" | "letterSpacing", value: T) => {
    const updatedTypography: ResponsiveTypographySettings = {
      ...responsiveTypography,
      [field]: {
        ...responsiveTypography[field],
        [activeBreakpoint]: value,
      },
    };

    if (isResponsive) {
      (props as TypographyModalPropsResponsive).onUpdate(updatedTypography);
    } else {
      (props as TypographyModalPropsNonResponsive).onUpdate(toNonResponsive(updatedTypography));
    }
  };

  // Handle non-responsive field change
  const handleFieldChange = <K extends keyof TypographySettings>(key: K, value: TypographySettings[K]) => {
    const updatedTypography: ResponsiveTypographySettings = {
      ...responsiveTypography,
      [key]: value,
    };

    if (isResponsive) {
      (props as TypographyModalPropsResponsive).onUpdate(updatedTypography);
    } else {
      (props as TypographyModalPropsNonResponsive).onUpdate(toNonResponsive(updatedTypography));
    }
  };

  return (
    <Dialog.Root open={open} onOpenChange={onOpenChange}>
      <Dialog.Portal>
        <Dialog.Overlay className="modal-overlay" />
        <Dialog.Content className="modal-content modal-content--lg">
          <div className="modal-header">
            <Dialog.Title className="modal-title">Typography Settings</Dialog.Title>
            <Dialog.Close asChild>
              <button className="modal-close" aria-label="Close">
                <Cross2Icon />
              </button>
            </Dialog.Close>
          </div>

          <div className="modal-body">
            {/* Responsive Breakpoint Toggle */}
            {isResponsive && (
              <div className="modal-field">
                <label className="modal-label">Breakpoint</label>
                <div className="modal-button-group">
                  {BREAKPOINTS.map((bp) => (
                    <button
                      key={bp.value}
                      type="button"
                      className={`modal-toggle-btn modal-toggle-btn--icon ${activeBreakpoint === bp.value ? "active" : ""}`}
                      onClick={() => setActiveBreakpoint(bp.value)}
                      title={bp.label}
                    >
                      {bp.icon}
                    </button>
                  ))}
                </div>
              </div>
            )}

            {/* Font Family */}
            <div className="modal-field">
              <label className="modal-label">Font Family</label>
              <FontSelect value={responsiveTypography.fontFamily} onValueChange={(value) => handleFieldChange("fontFamily", value)} />
            </div>

            {/* Font Size & Weight - Responsive */}
            <div className="modal-grid-2">
              <div className="modal-field">
                <label className="modal-label">
                  Font Size: {getValue(responsiveTypography.fontSize)}px
                  {isResponsive && <span className="modal-label__breakpoint">({activeBreakpoint})</span>}
                </label>
                <Slider
                  value={getValue(responsiveTypography.fontSize)}
                  onValueChange={(value) => handleResponsiveChange("fontSize", value)}
                  min={8}
                  max={150}
                  step={1}
                />
              </div>

              <div className="modal-field">
                <label className="modal-label">
                  Font Weight
                  {isResponsive && <span className="modal-label__breakpoint">({activeBreakpoint})</span>}
                </label>
                <Select
                  value={String(getValue(responsiveTypography.fontWeight))}
                  onValueChange={(value) => handleResponsiveChange("fontWeight", Number(value))}
                  options={FONT_WEIGHT_OPTIONS}
                />
              </div>
            </div>

            {/* Font Style */}
            <div className="modal-field">
              <label className="modal-label">Font Style</label>
              <ButtonGroup
                options={FONT_STYLE_OPTIONS}
                value={responsiveTypography.fontStyle}
                onChange={(value) => handleFieldChange("fontStyle", value as "normal" | "italic")}
              />
            </div>

            {/* Line Height & Letter Spacing */}
            <div className="modal-grid-2">
              <div className="modal-field">
                <label className="modal-label">Line Height: {responsiveTypography.lineHeight}</label>
                <Slider
                  value={responsiveTypography.lineHeight}
                  onValueChange={(value) => handleFieldChange("lineHeight", value)}
                  min={0.5}
                  max={3}
                  step={0.1}
                />
              </div>

              <div className="modal-field">
                <label className="modal-label">
                  Letter Spacing: {getValue(responsiveTypography.letterSpacing)}
                  px
                  {isResponsive && <span className="modal-label__breakpoint">({activeBreakpoint})</span>}
                </label>
                <Slider
                  value={getValue(responsiveTypography.letterSpacing)}
                  onValueChange={(value) => handleResponsiveChange("letterSpacing", value)}
                  min={-5}
                  max={20}
                  step={0.5}
                />
              </div>
            </div>

            {/* Text Transform */}
            <div className="modal-field">
              <label className="modal-label">Text Transform</label>
              <ButtonGroup
                options={TEXT_TRANSFORM_OPTIONS}
                value={responsiveTypography.textTransform}
                onChange={(value) => handleFieldChange("textTransform", value as TypographySettings["textTransform"])}
              />
            </div>

            {/* Text Decoration */}
            <div className="modal-field">
              <label className="modal-label">Text Decoration</label>
              <ButtonGroup
                options={TEXT_DECORATION_OPTIONS}
                value={responsiveTypography.textDecoration}
                onChange={(value) => handleFieldChange("textDecoration", value as TypographySettings["textDecoration"])}
              />
            </div>
          </div>

          <div className="modal-footer">
            <Dialog.Close asChild>
              <button className="oppb-button-secondary">Close</button>
            </Dialog.Close>
          </div>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}

export default TypographyModal;
