import React, { useCallback, useEffect, useState } from 'react';
import { ALargeSmall, AArrowDown, AArrowUp } from 'lucide-react';

// Constants for better maintainability
const TEXT_SIZE_OPTIONS = ['small', 'medium', 'large'] as const;
type TextSizeOption = (typeof TEXT_SIZE_OPTIONS)[number];

const TEXT_SIZE_STORAGE_KEY = 'bogam-text-size';
const DEFAULT_SIZE: TextSizeOption = 'small';
const TEXT_SIZE_CLASS_PREFIX = 'text-size';

// UI component constants
const TOGGLE_GROUP_CLASS =
  'toggle-group inline-flex h-10 items-center rounded-md border bg-background p-1 text-muted-foreground w-full';
const TOGGLE_BUTTON_CLASS =
  'flex-1 inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ' +
  'ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ' +
  'focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50';
const LOADING_PLACEHOLDER = <div className="h-10 w-full max-w-xl" aria-hidden="true"></div>;

export function TextSizeToggle() {
  const [textSize, setTextSize] = useState<TextSizeOption>(DEFAULT_SIZE);
  const [mounted, setMounted] = useState(false);

  // Initialize font size state once mounted
  useEffect(() => {
    setMounted(true);
    const storedPreferredTextSize = localStorage.getItem(TEXT_SIZE_STORAGE_KEY);

    // Validate stored preference against allowed options
    if (
      storedPreferredTextSize &&
      TEXT_SIZE_OPTIONS.includes(storedPreferredTextSize as TextSizeOption)
    ) {
      setTextSize(storedPreferredTextSize as TextSizeOption);
    }
  }, []);

  // Memoize the size application function for performance
  const updateArticleTextSize = useCallback(() => {
    const root = document.documentElement;

    // Generate all possible size classes
    const allSizeClasses = TEXT_SIZE_OPTIONS.map(size => `${TEXT_SIZE_CLASS_PREFIX}-${size}`);

    // Remove existing size classes
    root.classList.remove(...allSizeClasses);

    // Add the selected size class
    root.classList.add(`${TEXT_SIZE_CLASS_PREFIX}-${textSize}`);
  }, [textSize]);

  // Apply size changes when component mounts or textSize changes
  useEffect(() => {
    if (!mounted) return;

    // Apply size immediately
    updateArticleTextSize();

    // Save preference to localStorage
    localStorage.setItem(TEXT_SIZE_STORAGE_KEY, textSize);
  }, [textSize, mounted, updateArticleTextSize]);

  // Handle text size change with type safety
  const handleTextSizeChange = (newSize: TextSizeOption) => {
    setTextSize(newSize);
  };

  // Early return for SSR
  if (!mounted) {
    return LOADING_PLACEHOLDER;
  }

  return (
    <div className={TOGGLE_GROUP_CLASS} role="radiogroup" aria-label="Text size selection">
      <button
        onClick={() => handleTextSizeChange('small')}
        className={TOGGLE_BUTTON_CLASS}
        aria-pressed={textSize === 'small'}
        role="radio"
        aria-label="Small text size"
        type="button"
      >
        <AArrowDown className="h-4 w-4 mr-2" />
        Small
      </button>

      <button
        onClick={() => handleTextSizeChange('medium')}
        className={TOGGLE_BUTTON_CLASS}
        aria-pressed={textSize === 'medium'}
        role="radio"
        aria-label="Medium text size"
        type="button"
      >
        <ALargeSmall className="h-4 w-4 mr-2" />
        Medium
      </button>

      <button
        onClick={() => handleTextSizeChange('large')}
        className={TOGGLE_BUTTON_CLASS}
        aria-pressed={textSize === 'large'}
        role="radio"
        aria-label="Large text size"
        type="button"
      >
        <AArrowUp className="h-4 w-4 mr-2" />
        Large
      </button>
    </div>
  );
}
