'use client'

import React, { useState, useRef, useCallback, useMemo } from 'react'
import { useTheme } from '@/lib/ThemeContext'
import {
  SHADOWS,
  SHADOWS_DARK,
  MOTION,
  PARALLAX,
  MATERIALS,
  calculateParallax,
} from '@/lib/spatial-ui/depth-system'
import { usePerformance } from '@/lib/spatial-ui/PerformanceContext'

/**
 * SpatialCard - A card component with depth-aware interactions
 *
 * Features:
 * - Dynamic shadows that respond to hover/active states
 * - Subtle parallax effect based on cursor position
 * - Material-based styling (glass, solid, acrylic)
 * - Elevation changes with physics-based motion
 * - Performance-adaptive (degrades gracefully)
 */

export type CardMaterial = 'solid' | 'glass' | 'thinGlass' | 'thickGlass' | 'acrylic'
export type CardElevation = 'flat' | 'raised' | 'floating'

interface SpatialCardProps {
  children: React.ReactNode
  /** Material style */
  material?: CardMaterial
  /** Base elevation level */
  elevation?: CardElevation
  /** Enable hover lift effect */
  hoverLift?: boolean
  /** Enable subtle parallax on hover */
  parallax?: boolean
  /** Parallax intensity (uses PARALLAX constants) */
  parallaxIntensity?: number
  /** Click handler */
  onClick?: () => void
  /** Additional CSS classes */
  className?: string
  /** Custom padding */
  padding?: 'none' | 'sm' | 'md' | 'lg'
  /** Border radius */
  rounded?: 'none' | 'md' | 'lg' | 'xl' | '2xl' | '3xl'
  /** Glow color on hover (RGB values) */
  glowColor?: string
  /** Disable all effects */
  static?: boolean
}

const PADDING_MAP = {
  none: '',
  sm: 'p-3',
  md: 'p-4',
  lg: 'p-6',
}

const ROUNDED_MAP = {
  none: 'rounded-none',
  md: 'rounded-md',
  lg: 'rounded-lg',
  xl: 'rounded-xl',
  '2xl': 'rounded-2xl',
  '3xl': 'rounded-3xl',
}

const ELEVATION_SHADOWS = {
  flat: { rest: 'none', hover: 'sm', active: 'xs' },
  raised: { rest: 'sm', hover: 'lg', active: 'md' },
  floating: { rest: 'lg', hover: 'xl', active: 'lg' },
}

export function SpatialCard({
  children,
  material = 'glass',
  elevation = 'raised',
  hoverLift = true,
  parallax = false,
  parallaxIntensity = PARALLAX.subtle,
  onClick,
  className = '',
  padding = 'md',
  rounded = '2xl',
  glowColor,
  static: isStatic = false,
}: SpatialCardProps) {
  const { isDark } = useTheme()
  const { settings, reportAnimationStart, reportAnimationEnd, canStartAnimation } = usePerformance()

  const [isHovered, setIsHovered] = useState(false)
  const [isActive, setIsActive] = useState(false)
  const [parallaxOffset, setParallaxOffset] = useState({ x: 0, y: 0 })

  const cardRef = useRef<HTMLDivElement>(null)
  const animatingRef = useRef(false)

  // Determine if effects should be enabled
  const effectsEnabled = !isStatic && settings.enableShadows
  const parallaxEnabled = parallax && settings.enableParallax && !isStatic

  // Shadow key type (excludes glow function)
  type ShadowKey = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'

  // Get current shadow based on state
  const currentShadow = useMemo((): string => {
    if (!effectsEnabled) return 'none'

    const shadows = ELEVATION_SHADOWS[elevation]
    const shadowKey = (isActive ? shadows.active : isHovered ? shadows.hover : shadows.rest) as ShadowKey
    const shadowSet = isDark ? SHADOWS_DARK : SHADOWS

    // Get base shadow as string (not the glow function)
    const baseShadow = shadowSet[shadowKey] as string

    // Add glow effect on hover if specified
    if (isHovered && glowColor && settings.enableShadows) {
      const glowFn = isDark ? SHADOWS_DARK.glow : SHADOWS.glow
      return `${baseShadow}, ${glowFn(glowColor, 0.2)}`
    }

    return baseShadow
  }, [effectsEnabled, elevation, isActive, isHovered, isDark, glowColor, settings.enableShadows])

  // Get material styles
  const materialStyles = useMemo(() => {
    const mat = MATERIALS[material]
    const bg = isDark ? mat.backgroundDark : mat.background
    const border = isDark ? mat.borderDark : mat.border
    const blur = settings.enableBlur ? mat.blur * settings.blurIntensity : 0

    return {
      background: bg,
      backdropFilter: blur > 0 ? `blur(${blur}px)` : 'none',
      WebkitBackdropFilter: blur > 0 ? `blur(${blur}px)` : 'none',
      borderColor: border,
    }
  }, [material, isDark, settings.enableBlur, settings.blurIntensity])

  // Calculate transform based on state
  const transform = useMemo(() => {
    if (isStatic || !settings.enableSpringAnimations) {
      return 'translateY(0) scale(1)'
    }

    let y = 0
    let scale = 1

    if (isActive) {
      y = 1
      scale = 0.98
    } else if (isHovered && hoverLift) {
      y = -3
      scale = 1.01
    }

    // Add parallax offset
    const px = parallaxEnabled ? parallaxOffset.x : 0
    const py = parallaxEnabled ? parallaxOffset.y : 0

    return `translateY(${y}px) translateX(${px}px) translateZ(${py}px) scale(${scale})`
  }, [isStatic, settings.enableSpringAnimations, isActive, isHovered, hoverLift, parallaxEnabled, parallaxOffset])

  // Get transition timing
  const transitionDuration = useMemo(() => {
    const base = isActive ? MOTION.micro.duration : MOTION.standard.duration
    return Math.round(base * settings.animationSpeed)
  }, [isActive, settings.animationSpeed])

  // Handlers
  const handleMouseEnter = useCallback(() => {
    if (isStatic) return
    if (canStartAnimation() && !animatingRef.current) {
      animatingRef.current = true
      reportAnimationStart()
    }
    setIsHovered(true)
  }, [isStatic, canStartAnimation, reportAnimationStart])

  const handleMouseLeave = useCallback(() => {
    setIsHovered(false)
    setParallaxOffset({ x: 0, y: 0 })
    if (animatingRef.current) {
      animatingRef.current = false
      reportAnimationEnd()
    }
  }, [reportAnimationEnd])

  const handleMouseMove = useCallback(
    (e: React.MouseEvent) => {
      if (!parallaxEnabled || !cardRef.current) return

      const rect = cardRef.current.getBoundingClientRect()
      const offset = calculateParallax(
        e.clientX,
        e.clientY,
        rect,
        parallaxIntensity * settings.parallaxIntensity
      )
      setParallaxOffset(offset)
    },
    [parallaxEnabled, parallaxIntensity, settings.parallaxIntensity]
  )

  const handleMouseDown = useCallback(() => {
    if (!isStatic) setIsActive(true)
  }, [isStatic])

  const handleMouseUp = useCallback(() => {
    setIsActive(false)
  }, [])

  const handleClick = useCallback(() => {
    onClick?.()
  }, [onClick])

  return (
    <div
      ref={cardRef}
      className={`
        border
        ${PADDING_MAP[padding]}
        ${ROUNDED_MAP[rounded]}
        ${onClick ? 'cursor-pointer' : ''}
        ${className}
      `}
      style={{
        ...materialStyles,
        boxShadow: currentShadow,
        transform,
        transition: `
          box-shadow ${transitionDuration}ms ${MOTION.standard.easing},
          transform ${transitionDuration}ms ${settings.enableSpringAnimations ? MOTION.spring.easing : MOTION.standard.easing},
          background ${transitionDuration}ms ${MOTION.standard.easing}
        `,
        willChange: effectsEnabled ? 'transform, box-shadow' : 'auto',
      }}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      onMouseMove={handleMouseMove}
      onMouseDown={handleMouseDown}
      onMouseUp={handleMouseUp}
      onClick={handleClick}
    >
      {children}
    </div>
  )
}

/**
 * SpatialCardHeader - Header section for SpatialCard
 */
export function SpatialCardHeader({
  children,
  className = '',
}: {
  children: React.ReactNode
  className?: string
}) {
  const { isDark } = useTheme()

  return (
    <div
      className={`
        flex items-center justify-between mb-4
        ${isDark ? 'text-white' : 'text-slate-900'}
        ${className}
      `}
    >
      {children}
    </div>
  )
}

/**
 * SpatialCardContent - Main content area
 */
export function SpatialCardContent({
  children,
  className = '',
}: {
  children: React.ReactNode
  className?: string
}) {
  return <div className={className}>{children}</div>
}

/**
 * SpatialCardFooter - Footer section
 */
export function SpatialCardFooter({
  children,
  className = '',
}: {
  children: React.ReactNode
  className?: string
}) {
  const { isDark } = useTheme()

  return (
    <div
      className={`
        mt-4 pt-4 border-t
        ${isDark ? 'border-white/10' : 'border-slate-200'}
        ${className}
      `}
    >
      {children}
    </div>
  )
}
