'use client'

import React, { createContext, useContext, useState, useCallback, useRef, useEffect } from 'react'
import { MOTION, LAYERS } from './depth-system'
import { usePerformance } from './PerformanceContext'

/**
 * Focus Context - Manages focus mode for the UI
 *
 * When an element enters "focus mode", the rest of the UI dims and blurs,
 * creating a spotlight effect that helps users concentrate on the task at hand.
 *
 * This is particularly useful for:
 * - Replying to messages
 * - Editing content
 * - Modal-like interactions without actual modals
 */

interface FocusContextType {
  /** Whether focus mode is active */
  isFocused: boolean
  /** The ID of the focused element (if any) */
  focusedElementId: string | null
  /** Enter focus mode */
  enterFocus: (elementId: string) => void
  /** Exit focus mode */
  exitFocus: () => void
  /** Toggle focus mode */
  toggleFocus: (elementId: string) => void
}

const FocusContext = createContext<FocusContextType | null>(null)

interface FocusProviderProps {
  children: React.ReactNode
  /** Duration of the focus transition in ms */
  transitionDuration?: number
  /** Blur amount for unfocused elements (px) */
  blurAmount?: number
  /** Dim amount for unfocused elements (0-1) */
  dimAmount?: number
}

export function FocusProvider({
  children,
  transitionDuration = 300,
  blurAmount = 4,
  dimAmount = 0.6,
}: FocusProviderProps) {
  const [isFocused, setIsFocused] = useState(false)
  const [focusedElementId, setFocusedElementId] = useState<string | null>(null)
  const { settings } = usePerformance()

  const enterFocus = useCallback((elementId: string) => {
    setFocusedElementId(elementId)
    setIsFocused(true)
  }, [])

  const exitFocus = useCallback(() => {
    setIsFocused(false)
    // Delay clearing the ID to allow exit animation
    setTimeout(() => {
      setFocusedElementId(null)
    }, transitionDuration)
  }, [transitionDuration])

  const toggleFocus = useCallback(
    (elementId: string) => {
      if (isFocused && focusedElementId === elementId) {
        exitFocus()
      } else {
        enterFocus(elementId)
      }
    },
    [isFocused, focusedElementId, enterFocus, exitFocus]
  )

  // Keyboard handler for Escape
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape' && isFocused) {
        exitFocus()
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [isFocused, exitFocus])

  // Adaptive values based on performance
  const adaptiveBlur = settings.enableBlur ? blurAmount * settings.blurIntensity : 0
  const adaptiveDuration = Math.round(transitionDuration * settings.animationSpeed)

  return (
    <FocusContext.Provider
      value={{
        isFocused,
        focusedElementId,
        enterFocus,
        exitFocus,
        toggleFocus,
      }}
    >
      {/* Focus backdrop - dims and blurs unfocused content */}
      <div
        style={{
          position: 'fixed',
          inset: 0,
          zIndex: LAYERS.floating.zIndex,
          pointerEvents: isFocused ? 'auto' : 'none',
          opacity: isFocused ? 1 : 0,
          backgroundColor: `rgba(0, 0, 0, ${isFocused ? dimAmount : 0})`,
          backdropFilter: isFocused && adaptiveBlur > 0 ? `blur(${adaptiveBlur}px)` : 'none',
          WebkitBackdropFilter: isFocused && adaptiveBlur > 0 ? `blur(${adaptiveBlur}px)` : 'none',
          transition: `
            opacity ${adaptiveDuration}ms ${MOTION.standard.easing},
            backdrop-filter ${adaptiveDuration}ms ${MOTION.standard.easing}
          `,
        }}
        onClick={exitFocus}
        aria-hidden={!isFocused}
      />

      {children}
    </FocusContext.Provider>
  )
}

export function useFocus() {
  const context = useContext(FocusContext)
  if (!context) {
    return {
      isFocused: false,
      focusedElementId: null,
      enterFocus: () => {},
      exitFocus: () => {},
      toggleFocus: () => {},
    }
  }
  return context
}

/**
 * Hook to check if a specific element is focused
 */
export function useIsFocused(elementId: string): boolean {
  const { isFocused, focusedElementId } = useFocus()
  return isFocused && focusedElementId === elementId
}

/**
 * FocusTarget - Wrapper that makes children focusable
 */
interface FocusTargetProps {
  children: React.ReactNode
  /** Unique ID for this focus target */
  id: string
  /** Additional class names */
  className?: string
  /** Style overrides */
  style?: React.CSSProperties
}

export function FocusTarget({ children, id, className = '', style }: FocusTargetProps) {
  const { isFocused, focusedElementId } = useFocus()
  const { settings } = usePerformance()

  const isThisElement = focusedElementId === id
  const shouldElevate = isFocused && isThisElement

  const duration = Math.round(MOTION.emphasis.duration * settings.animationSpeed)

  return (
    <div
      className={className}
      style={{
        ...style,
        position: 'relative',
        zIndex: shouldElevate ? LAYERS.overlay.zIndex + 1 : 'auto',
        transition: `z-index ${duration}ms ${MOTION.standard.easing}`,
      }}
      data-focus-target={id}
      data-focused={shouldElevate}
    >
      {children}
    </div>
  )
}
