import { useEffect, useRef } from 'react'
import { X, Loader2, AlertCircle } from 'lucide-react'
import { useSettings, useUpdateSettings, useAvailableModels } from '../hooks/useProjects'

interface SettingsModalProps {
  onClose: () => void
}

export function SettingsModal({ onClose }: SettingsModalProps) {
  const { data: settings, isLoading, isError, refetch } = useSettings()
  const { data: modelsData } = useAvailableModels()
  const updateSettings = useUpdateSettings()
  const modalRef = useRef<HTMLDivElement>(null)
  const closeButtonRef = useRef<HTMLButtonElement>(null)

  // Focus trap - keep focus within modal
  useEffect(() => {
    const modal = modalRef.current
    if (!modal) return

    // Focus the close button when modal opens
    closeButtonRef.current?.focus()

    const focusableElements = modal.querySelectorAll<HTMLElement>(
      'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
    )
    const firstElement = focusableElements[0]
    const lastElement = focusableElements[focusableElements.length - 1]

    const handleTabKey = (e: KeyboardEvent) => {
      if (e.key !== 'Tab') return

      if (e.shiftKey) {
        if (document.activeElement === firstElement) {
          e.preventDefault()
          lastElement?.focus()
        }
      } else {
        if (document.activeElement === lastElement) {
          e.preventDefault()
          firstElement?.focus()
        }
      }
    }

    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        onClose()
      }
    }

    document.addEventListener('keydown', handleTabKey)
    document.addEventListener('keydown', handleEscape)

    return () => {
      document.removeEventListener('keydown', handleTabKey)
      document.removeEventListener('keydown', handleEscape)
    }
  }, [onClose])

  const handleYoloToggle = () => {
    if (settings && !updateSettings.isPending) {
      updateSettings.mutate({ yolo_mode: !settings.yolo_mode })
    }
  }

  const handleModelChange = (modelId: string) => {
    if (!updateSettings.isPending) {
      updateSettings.mutate({ model: modelId })
    }
  }

  const handleTestingRatioChange = (ratio: number) => {
    if (!updateSettings.isPending) {
      updateSettings.mutate({ testing_agent_ratio: ratio })
    }
  }

  const handleCountTestingToggle = () => {
    if (settings && !updateSettings.isPending) {
      updateSettings.mutate({ count_testing_in_concurrency: !settings.count_testing_in_concurrency })
    }
  }

  const models = modelsData?.models ?? []
  const isSaving = updateSettings.isPending

  return (
    <div
      className="neo-modal-backdrop"
      onClick={onClose}
      role="presentation"
    >
      <div
        ref={modalRef}
        className="neo-modal w-full max-w-sm p-6"
        onClick={(e) => e.stopPropagation()}
        role="dialog"
        aria-labelledby="settings-title"
        aria-modal="true"
      >
        {/* Header */}
        <div className="flex items-center justify-between mb-6">
          <h2 id="settings-title" className="font-display text-xl font-bold">
            Settings
            {isSaving && (
              <Loader2 className="inline-block ml-2 animate-spin" size={16} />
            )}
          </h2>
          <button
            ref={closeButtonRef}
            onClick={onClose}
            className="neo-btn neo-btn-ghost p-2"
            aria-label="Close settings"
          >
            <X size={20} />
          </button>
        </div>

        {/* Loading State */}
        {isLoading && (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="animate-spin" size={24} />
            <span className="ml-2">Loading settings...</span>
          </div>
        )}

        {/* Error State */}
        {isError && (
          <div className="p-4 bg-[var(--color-neo-error-bg)] text-[var(--color-neo-error-text)] border-3 border-[var(--color-neo-error-border)] mb-4">
            <div className="flex items-center gap-2">
              <AlertCircle size={18} />
              <span>Failed to load settings</span>
            </div>
            <button
              onClick={() => refetch()}
              className="mt-2 underline text-sm hover:opacity-70 transition-opacity"
            >
              Retry
            </button>
          </div>
        )}

        {/* Settings Content */}
        {settings && !isLoading && (
          <div className="space-y-6">
            {/* YOLO Mode Toggle */}
            <div>
              <div className="flex items-center justify-between">
                <div>
                  <label
                    id="yolo-label"
                    className="font-display font-bold text-base"
                  >
                    YOLO Mode
                  </label>
                  <p className="text-sm text-[var(--color-neo-text-secondary)] mt-1">
                    Skip testing for rapid prototyping
                  </p>
                </div>
                <button
                  onClick={handleYoloToggle}
                  disabled={isSaving}
                  className={`relative w-14 h-8 rounded-none border-3 border-[var(--color-neo-border)] transition-colors ${
                    settings.yolo_mode
                      ? 'bg-[var(--color-neo-pending)]'
                      : 'bg-[var(--color-neo-card)]'
                  } ${isSaving ? 'opacity-50 cursor-not-allowed' : ''}`}
                  role="switch"
                  aria-checked={settings.yolo_mode}
                  aria-labelledby="yolo-label"
                >
                  <span
                    className={`absolute top-1 w-5 h-5 bg-[var(--color-neo-border)] transition-transform ${
                      settings.yolo_mode ? 'left-7' : 'left-1'
                    }`}
                  />
                </button>
              </div>
            </div>

            {/* Model Selection - Radio Group */}
            <div>
              <label
                id="model-label"
                className="font-display font-bold text-base block mb-2"
              >
                Model
              </label>
              <div
                className="flex border-3 border-[var(--color-neo-border)]"
                role="radiogroup"
                aria-labelledby="model-label"
              >
                {models.map((model) => (
                  <button
                    key={model.id}
                    onClick={() => handleModelChange(model.id)}
                    disabled={isSaving}
                    role="radio"
                    aria-checked={settings.model === model.id}
                    className={`flex-1 py-3 px-4 font-display font-bold text-sm transition-colors ${
                      settings.model === model.id
                        ? 'bg-[var(--color-neo-accent)] text-[var(--color-neo-text-on-bright)]'
                        : 'bg-[var(--color-neo-card)] text-[var(--color-neo-text)] hover:bg-[var(--color-neo-hover-subtle)]'
                    } ${isSaving ? 'opacity-50 cursor-not-allowed' : ''}`}
                  >
                    {model.name}
                  </button>
                ))}
              </div>
            </div>

            {/* Testing Agent Ratio */}
            <div>
              <label
                id="testing-ratio-label"
                className="font-display font-bold text-base block mb-1"
              >
                Testing Agents per Coding Agent
              </label>
              <p className="text-sm text-[var(--color-neo-text-secondary)] mb-2">
                Regression testing agents spawned per coding agent (0 = disabled)
              </p>
              <div
                className="flex border-3 border-[var(--color-neo-border)]"
                role="radiogroup"
                aria-labelledby="testing-ratio-label"
              >
                {[0, 1, 2, 3].map((ratio) => (
                  <button
                    key={ratio}
                    onClick={() => handleTestingRatioChange(ratio)}
                    disabled={isSaving}
                    role="radio"
                    aria-checked={settings.testing_agent_ratio === ratio}
                    className={`flex-1 py-2 px-3 font-display font-bold text-sm transition-colors ${
                      settings.testing_agent_ratio === ratio
                        ? 'bg-[var(--color-neo-progress)] text-[var(--color-neo-text)]'
                        : 'bg-[var(--color-neo-card)] text-[var(--color-neo-text)] hover:bg-[var(--color-neo-hover-subtle)]'
                    } ${isSaving ? 'opacity-50 cursor-not-allowed' : ''}`}
                  >
                    {ratio}
                  </button>
                ))}
              </div>
            </div>

            {/* Count Testing in Concurrency Toggle */}
            <div>
              <div className="flex items-center justify-between">
                <div>
                  <label
                    id="count-testing-label"
                    className="font-display font-bold text-base"
                  >
                    Count Testing in Concurrency
                  </label>
                  <p className="text-sm text-[var(--color-neo-text-secondary)] mt-1">
                    If enabled, testing agents count toward the concurrency limit
                  </p>
                </div>
                <button
                  onClick={handleCountTestingToggle}
                  disabled={isSaving}
                  className={`relative w-14 h-8 rounded-none border-3 border-[var(--color-neo-border)] transition-colors ${
                    settings.count_testing_in_concurrency
                      ? 'bg-[var(--color-neo-progress)]'
                      : 'bg-[var(--color-neo-card)]'
                  } ${isSaving ? 'opacity-50 cursor-not-allowed' : ''}`}
                  role="switch"
                  aria-checked={settings.count_testing_in_concurrency}
                  aria-labelledby="count-testing-label"
                >
                  <span
                    className={`absolute top-1 w-5 h-5 bg-[var(--color-neo-border)] transition-transform ${
                      settings.count_testing_in_concurrency ? 'left-7' : 'left-1'
                    }`}
                  />
                </button>
              </div>
            </div>

            {/* Update Error */}
            {updateSettings.isError && (
              <div className="p-3 bg-[var(--color-neo-error-bg)] border-3 border-[var(--color-neo-error-border)] text-[var(--color-neo-error-text)] text-sm">
                Failed to save settings. Please try again.
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  )
}
