import { useState, useEffect } from 'react'
import { Button } from './ui'
import { t } from '@/lib/i18n'
import { getReadingModeSettings, saveReadingModeSettings, type ReadingModeSettings } from '@/lib/readingModePreferences'

const DEFAULT_SETTINGS: ReadingModeSettings = {
  maxWidth: 'medium',
  fontSize: 'medium',
  lineHeight: 'normal',
}

interface ReadingModeProps {
  children: React.ReactNode
  className?: string
}

function useReadingModeState(): {
  isActive: boolean
  setIsActive: (value: boolean) => void
  settings: ReadingModeSettings
  setSettings: (settings: ReadingModeSettings) => void
} {
  const [isActive, setIsActive] = useState(false)
  const [settings, setSettings] = useState<ReadingModeSettings>(DEFAULT_SETTINGS)

  useEffect(() => {
    const load = async (): Promise<void> => {
      try {
        const saved = await getReadingModeSettings()
        if (saved !== null) {
          setSettings(saved)
        }
      } catch (error) {
        console.error('Error loading reading mode settings:', error)
      }
    }
    void load()
  }, [])

  useEffect(() => {
    if (isActive) {
      const save = async (): Promise<void> => {
        try {
          await saveReadingModeSettings(settings)
        } catch (error) {
          console.error('Error saving reading mode settings:', error)
        }
      }
      void save()
    }
  }, [isActive, settings])

  return { isActive, setIsActive, settings, setSettings }
}

export function ReadingMode({ children, className = '' }: ReadingModeProps): React.ReactElement {
  const { isActive, setIsActive, settings, setSettings } = useReadingModeState()
  const readingModeClasses = isActive ? getReadingModeClasses(settings) : ''
  const containerClasses = isActive ? `reading-mode ${readingModeClasses}` : ''

  return (
    <div className={className}>
      <ReadingModeToggle isActive={isActive} onToggle={() => setIsActive(!isActive)} />
      {isActive && (
        <ReadingModeControls settings={settings} onSettingsChange={setSettings} />
      )}
      <div className={containerClasses}>
        {children}
      </div>
    </div>
  )
}

function ReadingModeToggle({ isActive, onToggle }: { isActive: boolean; onToggle: () => void }): React.ReactElement {
  return (
    <Button
      type="button"
      variant="ghost"
      size="small"
      onClick={onToggle}
      aria-label={isActive ? t('readingMode.disable') : t('readingMode.enable')}
      className="mb-4"
    >
      {isActive ? t('readingMode.disable') : t('readingMode.enable')}
    </Button>
  )
}

function ReadingModeControls({
  settings,
  onSettingsChange,
}: {
  settings: ReadingModeSettings
  onSettingsChange: (settings: ReadingModeSettings) => void
}): React.ReactElement {
  return (
    <div className="mb-4 p-4 bg-cyber-dark border border-neon-cyan/30 rounded-lg space-y-4">
      <WidthControl settings={settings} onSettingsChange={onSettingsChange} />
      <FontSizeControl settings={settings} onSettingsChange={onSettingsChange} />
      <LineHeightControl settings={settings} onSettingsChange={onSettingsChange} />
    </div>
  )
}

function WidthControl({
  settings,
  onSettingsChange,
}: {
  settings: ReadingModeSettings
  onSettingsChange: (settings: ReadingModeSettings) => void
}): React.ReactElement {
  const widths: ReadingModeSettings['maxWidth'][] = ['narrow', 'medium', 'wide', 'full']
  return (
    <div>
      <label className="block text-sm font-medium text-neon-cyan mb-2">
        {t('readingMode.maxWidth')}
      </label>
      <div className="flex gap-2">
        {widths.map((width) => (
          <Button
            key={width}
            type="button"
            variant={settings.maxWidth === width ? 'primary' : 'secondary'}
            size="small"
            onClick={() => onSettingsChange({ ...settings, maxWidth: width })}
          >
            {t(`readingMode.maxWidth.${width}`)}
          </Button>
        ))}
      </div>
    </div>
  )
}

function FontSizeControl({
  settings,
  onSettingsChange,
}: {
  settings: ReadingModeSettings
  onSettingsChange: (settings: ReadingModeSettings) => void
}): React.ReactElement {
  const sizes: ReadingModeSettings['fontSize'][] = ['small', 'medium', 'large', 'xlarge']
  return (
    <div>
      <label className="block text-sm font-medium text-neon-cyan mb-2">
        {t('readingMode.fontSize')}
      </label>
      <div className="flex gap-2">
        {sizes.map((size) => (
          <Button
            key={size}
            type="button"
            variant={settings.fontSize === size ? 'primary' : 'secondary'}
            size="small"
            onClick={() => onSettingsChange({ ...settings, fontSize: size })}
          >
            {t(`readingMode.fontSize.${size}`)}
          </Button>
        ))}
      </div>
    </div>
  )
}

function LineHeightControl({
  settings,
  onSettingsChange,
}: {
  settings: ReadingModeSettings
  onSettingsChange: (settings: ReadingModeSettings) => void
}): React.ReactElement {
  const heights: ReadingModeSettings['lineHeight'][] = ['tight', 'normal', 'relaxed']
  return (
    <div>
      <label className="block text-sm font-medium text-neon-cyan mb-2">
        {t('readingMode.lineHeight')}
      </label>
      <div className="flex gap-2">
        {heights.map((height) => (
          <Button
            key={height}
            type="button"
            variant={settings.lineHeight === height ? 'primary' : 'secondary'}
            size="small"
            onClick={() => onSettingsChange({ ...settings, lineHeight: height })}
          >
            {t(`readingMode.lineHeight.${height}`)}
          </Button>
        ))}
      </div>
    </div>
  )
}

function getReadingModeClasses(settings: ReadingModeSettings): string {
  const widthClasses: Record<ReadingModeSettings['maxWidth'], string> = {
    narrow: 'max-w-2xl',
    medium: 'max-w-3xl',
    wide: 'max-w-5xl',
    full: 'max-w-full',
  }
  const fontSizeClasses: Record<ReadingModeSettings['fontSize'], string> = {
    small: 'text-sm',
    medium: 'text-base',
    large: 'text-lg',
    xlarge: 'text-xl',
  }
  const lineHeightClasses: Record<ReadingModeSettings['lineHeight'], string> = {
    tight: 'leading-tight',
    normal: 'leading-normal',
    relaxed: 'leading-relaxed',
  }

  return `${widthClasses[settings.maxWidth]} ${fontSizeClasses[settings.fontSize]} ${lineHeightClasses[settings.lineHeight]} mx-auto`
}
