'use client'

import {
  useCallback,
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
  type ComponentType,
  type RefObject,
} from 'react'
import { ChatCircle, Database, GitBranch } from '@phosphor-icons/react'

import { cn } from '@/lib/utils'

export type WorkspaceMode = 'chat' | 'flows' | 'knowledge'

type WorkspaceModeToggleProps = {
  mode: WorkspaceMode
  onModeChange: (mode: WorkspaceMode) => void
  sessionsUnreadCount?: number
  flowsUnreadCount?: number
  knowledgePendingCount?: number
  hideFlows?: boolean
  className?: string
}

type ModeButtonProps = {
  active: boolean
  badgeDescription?: 'pending' | 'unread'
  badgeCount?: number
  buttonRef: RefObject<HTMLButtonElement | null>
  icon: ComponentType<{ size?: number; weight?: 'regular' | 'bold' | 'fill' }>
  label: string
  onClick: () => void
}

const useIsomorphicLayoutEffect =
  typeof window !== 'undefined' ? useLayoutEffect : useEffect

function ModeButton({
  active,
  badgeDescription = 'pending',
  badgeCount,
  buttonRef,
  icon: Icon,
  label,
  onClick,
}: ModeButtonProps) {
  const showBadge = typeof badgeCount === 'number' && badgeCount > 0
  const badgeLabel = badgeCount && badgeCount > 99 ? '99+' : String(badgeCount ?? 0)

  return (
    <button
      ref={buttonRef}
      type="button"
      onClick={onClick}
      aria-pressed={active}
      className={cn(
        'relative z-10 flex h-7 items-center gap-1.5 rounded-full px-4 text-[12px] font-medium transition-colors duration-200',
        active
          ? 'text-primary-foreground'
          : 'text-muted-foreground hover:text-foreground'
      )}
    >
      <Icon size={13} weight={active ? 'fill' : 'bold'} />
      <span className="leading-none">{label}</span>
      {showBadge ? (
        <span
          aria-label={`${badgeCount} ${badgeDescription}`}
          className={cn(
            '-mr-1 flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-[10px] font-semibold leading-none',
            active
              ? 'bg-primary-foreground/20 text-primary-foreground'
              : 'bg-primary text-primary-foreground'
          )}
        >
          {badgeLabel}
        </span>
      ) : null}
    </button>
  )
}

export function WorkspaceModeToggle({
  mode,
  onModeChange,
  sessionsUnreadCount = 0,
  flowsUnreadCount = 0,
  knowledgePendingCount = 0,
  hideFlows = false,
  className,
}: WorkspaceModeToggleProps) {
  const containerRef = useRef<HTMLDivElement>(null)
  const chatRef = useRef<HTMLButtonElement>(null)
  const flowsRef = useRef<HTMLButtonElement>(null)
  const knowledgeRef = useRef<HTMLButtonElement>(null)
  const activeButtonRef = mode === 'chat' ? chatRef : mode === 'flows' ? flowsRef : knowledgeRef

  const [indicator, setIndicator] = useState<{ left: number; width: number } | null>(null)
  const [hasAnimated, setHasAnimated] = useState(false)

  const updateIndicator = useCallback(() => {
    const button = activeButtonRef.current
    const container = containerRef.current
    if (!button || !container) return

    const containerRect = container.getBoundingClientRect()
    const buttonRect = button.getBoundingClientRect()
    setIndicator({
      left: buttonRect.left - containerRect.left,
      width: buttonRect.width,
    })
  }, [activeButtonRef])

  useIsomorphicLayoutEffect(() => {
    updateIndicator()
  }, [hideFlows, knowledgePendingCount, sessionsUnreadCount, flowsUnreadCount, updateIndicator])

  useEffect(() => {
    const button = activeButtonRef.current
    const container = containerRef.current
    if (!button || !container || typeof ResizeObserver === 'undefined') return

    const observer = new ResizeObserver(() => updateIndicator())
    observer.observe(button)
    observer.observe(container)
    return () => observer.disconnect()
  }, [activeButtonRef, updateIndicator])

  useEffect(() => {
    if (!indicator || hasAnimated) return
    const frame = requestAnimationFrame(() => setHasAnimated(true))
    return () => cancelAnimationFrame(frame)
  }, [indicator, hasAnimated])

  return (
    <div
      ref={containerRef}
      className={cn(
        'relative inline-flex h-9 items-center gap-0.5 rounded-full border border-border/30 bg-black/[0.05] px-[3px] py-1 dark:bg-black/30',
        className
      )}
    >
      <span
        aria-hidden
        className={cn(
          'pointer-events-none absolute top-1/2 h-7 -translate-y-1/2 rounded-full bg-primary shadow-sm',
          indicator ? 'opacity-100' : 'opacity-0',
          hasAnimated && 'transition-[left,width] duration-300 ease-out'
        )}
        style={indicator ? { left: indicator.left, width: indicator.width } : undefined}
      />
      <ModeButton
        active={mode === 'chat'}
        badgeCount={sessionsUnreadCount}
        badgeDescription="unread"
        buttonRef={chatRef}
        icon={ChatCircle}
        label="Sessions"
        onClick={() => onModeChange('chat')}
      />
      {hideFlows ? null : (
        <ModeButton
          active={mode === 'flows'}
          badgeCount={flowsUnreadCount}
          badgeDescription="unread"
          buttonRef={flowsRef}
          icon={GitBranch}
          label="Flows"
          onClick={() => onModeChange('flows')}
        />
      )}
      <ModeButton
        active={mode === 'knowledge'}
        badgeDescription="pending"
        badgeCount={knowledgePendingCount}
        buttonRef={knowledgeRef}
        icon={Database}
        label="Knowledge"
        onClick={() => onModeChange('knowledge')}
      />
    </div>
  )
}
