import { useState, type ReactNode } from 'react'
import { motion, AnimatePresence, LayoutGroup, type PanInfo } from 'framer-motion'
import { cn } from '../../lib/utils'
import { Grid3X3, Layers, LayoutList } from 'lucide-react'

export type LayoutMode = 'stack' | 'grid' | 'list'

export interface CardData {
  id: string
  title: string
  description: string
  icon?: ReactNode
  color?: string
}

export interface MorphingCardStackProps {
  cards?: CardData[]
  className?: string
  defaultLayout?: LayoutMode
  onCardClick?: (card: CardData) => void
}

const layoutIcons = {
  stack: Layers,
  grid: Grid3X3,
  list: LayoutList,
}

const SWIPE_THRESHOLD = 50

export function Component({
  cards = [],
  className,
  defaultLayout = 'stack',
  onCardClick,
}: MorphingCardStackProps) {
  const [layout, setLayout] = useState<LayoutMode>(defaultLayout)
  const [expandedCard, setExpandedCard] = useState<string | null>(null)
  const [activeIndex, setActiveIndex] = useState(0)
  const [isDragging, setIsDragging] = useState(false)

  if (!cards || cards.length === 0) {
    return null
  }

  const handleDragEnd = (
    _event: MouseEvent | TouchEvent | PointerEvent,
    info: PanInfo,
  ) => {
    const { offset, velocity } = info
    const swipe = Math.abs(offset.x) * velocity.x

    if (offset.x < -SWIPE_THRESHOLD || swipe < -1000) {
      // Swiped left - go to next card
      setActiveIndex((prev) => (prev + 1) % cards.length)
    } else if (offset.x > SWIPE_THRESHOLD || swipe > 1000) {
      // Swiped right - go to previous card
      setActiveIndex((prev) => (prev - 1 + cards.length) % cards.length)
    }
    setIsDragging(false)
  }

  const getStackOrder = () => {
    const reordered = []
    for (let i = 0; i < cards.length; i++) {
      const index = (activeIndex + i) % cards.length
      reordered.push({ ...cards[index], stackPosition: i })
    }
    return reordered.reverse() // Reverse so top card renders last (on top)
  }

  const getLayoutStyles = (stackPosition: number) => {
    switch (layout) {
      case 'stack':
        return {
          top: stackPosition * 8,
          left: stackPosition * 8,
          zIndex: cards.length - stackPosition,
          rotate: (stackPosition - 1) * 2,
        }
      case 'grid':
        return {
          top: 0,
          left: 0,
          zIndex: 1,
          rotate: 0,
        }
      case 'list':
        return {
          top: 0,
          left: 0,
          zIndex: 1,
          rotate: 0,
        }
    }
  }

  const containerStyles = {
    stack: 'relative h-[380px] w-[320px] sm:w-[380px]',
    grid: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 w-full max-w-[1100px]',
    list: 'flex flex-col gap-4 w-full max-w-3xl',
  }

  const displayCards =
    layout === 'stack'
      ? getStackOrder()
      : cards.map((c, i) => ({ ...c, stackPosition: i }))

  return (
    <div className={cn('space-y-8', className)}>
      {/* Layout Toggle */}
      <div 
        className="flex items-center justify-center gap-1 rounded-full p-1.5 w-fit mx-auto backdrop-blur-sm"
        style={{ border: '1px solid var(--lp-line)', background: 'var(--lp-chip)' }}
      >
        {(Object.keys(layoutIcons) as LayoutMode[]).map((mode) => {
          const Icon = layoutIcons[mode]
          return (
            <button
              key={mode}
              onClick={() => setLayout(mode)}
              className={cn(
                'rounded-full p-2.5 transition-all cursor-pointer',
                layout === mode
                  ? 'bg-[var(--lp-text)] text-[var(--lp-bg)] shadow-sm'
                  : 'text-[var(--lp-muted)] hover:text-[var(--lp-text)] hover:bg-[var(--lp-line)]/50',
              )}
              aria-label={`Switch to ${mode} layout`}
            >
              <Icon className="h-[18px] w-[18px]" />
            </button>
          )
        })}
      </div>

      {/* Cards Container */}
      <LayoutGroup>
        <motion.div layout className={cn(containerStyles[layout], 'mx-auto')}>
          <AnimatePresence mode="popLayout">
            {displayCards.map((card) => {
              const styles = getLayoutStyles(card.stackPosition)
              const isExpanded = expandedCard === card.id
              const isTopCard = layout === 'stack' && card.stackPosition === 0

              return (
                <motion.div
                  key={card.id}
                  layoutId={card.id}
                  initial={{ opacity: 0, scale: 0.8 }}
                  animate={{
                    opacity: 1,
                    scale: isExpanded ? 1.02 : 1,
                    x: 0,
                    ...styles,
                  }}
                  exit={{ opacity: 0, scale: 0.8, x: -200 }}
                  transition={{
                    type: 'spring',
                    stiffness: 300,
                    damping: 30,
                  }}
                  drag={isTopCard ? 'x' : false}
                  dragConstraints={{ left: 0, right: 0 }}
                  dragElastic={0.7}
                  onDragStart={() => setIsDragging(true)}
                  onDragEnd={handleDragEnd}
                  whileDrag={{ scale: 1.02, cursor: 'grabbing' }}
                  onClick={() => {
                    if (isDragging) return
                    setExpandedCard(isExpanded ? null : card.id)
                    onCardClick?.(card)
                  }}
                  className={cn(
                    'cursor-pointer rounded-2xl overflow-hidden transition-colors',
                    layout === 'stack' && 'absolute w-full h-full p-8',
                    layout === 'stack' &&
                      isTopCard &&
                      'cursor-grab active:cursor-grabbing',
                    layout === 'grid' && 'p-8',
                    layout === 'list' && 'p-6 md:p-8',
                  )}
                  style={{
                    backgroundColor: 'var(--lp-bg)',
                    border: isExpanded ? '1px solid var(--lp-text)' : '1px solid var(--lp-line)',
                    boxShadow: layout === 'stack' ? '0 10px 40px -10px rgba(0,0,0,0.2)' : 'none',
                  }}
                >
                  <div className={cn(
                    "flex",
                    layout === 'list' ? "flex-col sm:flex-row sm:items-center gap-6" : "flex-col items-start gap-5"
                  )}>
                    {card.icon && (
                      <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-secondary text-foreground">
                        {card.icon}
                      </div>
                    )}
                    <div className="min-w-0 flex-1">
                      <h3 
                        className="font-semibold"
                        style={{ 
                          color: 'var(--lp-text)',
                          fontFamily: 'var(--font-display)',
                          fontSize: layout === 'grid' ? '1.25rem' : '1.25rem',
                          lineHeight: 1.2
                        }}
                      >
                        {card.title}
                      </h3>
                      <p
                        className="mt-2.5 leading-relaxed"
                        style={{ 
                          color: 'var(--lp-muted)',
                          fontSize: layout === 'stack' ? '0.95rem' : '1rem'
                        }}
                      >
                        {card.description}
                      </p>
                    </div>
                  </div>

                  {isTopCard && (
                    <div className="absolute bottom-6 left-0 right-0 text-center">
                      <span className="text-[11px] uppercase tracking-widest" style={{ color: 'var(--lp-eyebrow)', fontFamily: 'var(--font-mono)' }}>
                        Swipe to navigate
                      </span>
                    </div>
                  )}
                </motion.div>
              )
            })}
          </AnimatePresence>
        </motion.div>
      </LayoutGroup>

      {layout === 'stack' && cards.length > 1 && (
        <div className="flex justify-center gap-1.5 mt-16 relative z-20">
          {cards.map((_, index) => (
            <button
              key={index}
              onClick={() => setActiveIndex(index)}
              className={cn(
                'h-1.5 rounded-full transition-all cursor-pointer',
                index === activeIndex
                  ? 'w-4 bg-primary'
                  : 'w-1.5 bg-muted-foreground/30 hover:bg-muted-foreground/50',
              )}
              aria-label={`Go to card ${index + 1}`}
            />
          ))}
        </div>
      )}
    </div>
  )
}
