'use client'

import React from 'react'
import { cn } from '../../utils'
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
  PopoverArrow,
} from '../Popover/Popover'
import {
  TooltipContent as TooltipPrimitiveContent,
  TooltipProvider as TooltipPrimitiveProvider,
  Tooltip as TooltipPrimitive,
  TooltipTrigger as TooltipPrimitiveTrigger,
  TooltipArrow as TooltipPrimitiveArrow,
} from './Tooltip'

type ResponsiveMode = 'mobile' | 'desktop'
const ResponsiveModeContext = React.createContext<ResponsiveMode>('mobile')

export type ResponsiveTooltipProps = React.PropsWithChildren<{
  /** Opens the tooltip/popover by default in uncontrolled usage. */
  defaultOpen?: boolean
  /** Controls the open state. Pair with `onOpenChange` for controlled usage. */
  open?: boolean
  /** Called when the tooltip/popover requests an open state change. */
  onOpenChange?: (open: boolean) => void
}>

/**
 * Tooltip that adapts to the device: renders a hover Tooltip on desktop and a
 * tap Popover on mobile. Renders both simultaneously and uses CSS to show the
 * right one. Compose with ResponsiveTooltipTrigger and ResponsiveTooltipContent.
 */
function ResponsiveTooltip({ children, ...props }: ResponsiveTooltipProps) {
  return (
    <TooltipPrimitiveProvider>
      <ResponsiveModeContext.Provider value="mobile">
        <Popover {...props}>{children}</Popover>
      </ResponsiveModeContext.Provider>

      <ResponsiveModeContext.Provider value="desktop">
        <TooltipPrimitive delayDuration={200} {...props}>
          {children}
        </TooltipPrimitive>
      </ResponsiveModeContext.Provider>
    </TooltipPrimitiveProvider>
  )
}

export type ResponsiveTooltipTriggerProps = React.PropsWithChildren<{
  asChild?: boolean
  className?: string
}>

/** Trigger element for ResponsiveTooltip. Renders as a Popover trigger on mobile and a Tooltip trigger on desktop. */
function ResponsiveTooltipTrigger({
  children,
  className,
  ...props
}: ResponsiveTooltipTriggerProps) {
  const mode = React.useContext(ResponsiveModeContext)

  if (mode === 'mobile') {
    return (
      <PopoverTrigger
        className={cn('md:hidden', className)}
        data-responsive-tooltip="trigger-mobile"
        {...props}
      >
        {children}
      </PopoverTrigger>
    )
  }

  return (
    <TooltipPrimitiveTrigger
      className={cn('max-md:hidden', className)}
      data-responsive-tooltip="trigger-desktop"
      {...props}
    >
      {children}
    </TooltipPrimitiveTrigger>
  )
}

function ResponsiveTooltipArrow({ ...props }) {
  const mode = React.useContext(ResponsiveModeContext)

  if (mode === 'mobile') {
    return <PopoverArrow {...props} />
  }

  return <TooltipPrimitiveArrow {...props} />
}

export type ResponsiveTooltipContentProps = {
  asChild?: boolean | undefined
  /** Which side of the trigger to display the content on. */
  side?: 'top' | 'right' | 'bottom' | 'left'
  /** Alignment along the trigger's cross-axis. */
  align?: 'start' | 'center' | 'end'
  /** When true, hides the directional arrow. Defaults to false. */
  hideArrow?: boolean
  className?: string
}

/**
 * Content panel for ResponsiveTooltip. Renders as a Popover on mobile and a
 * Tooltip on desktop. Shows an arrow by default; set `hideArrow` to suppress it.
 */
function ResponsiveTooltipContent({
  children,
  hideArrow = false,
  className,
  ...props
}: React.PropsWithChildren<ResponsiveTooltipContentProps>) {
  const mode = React.useContext(ResponsiveModeContext)

  if (mode === 'mobile') {
    return (
      <PopoverContent
        className={cn('md:hidden', className)}
        arrowPadding={16}
        {...props}
      >
        {!hideArrow && <ResponsiveTooltipArrow />}
        {children}
      </PopoverContent>
    )
  }

  return (
    <TooltipPrimitiveContent
      className={cn('max-md:hidden', className)}
      arrowPadding={16}
      {...props}
    >
      {!hideArrow && <ResponsiveTooltipArrow />}
      {children}
    </TooltipPrimitiveContent>
  )
}

export { ResponsiveTooltip, ResponsiveTooltipTrigger, ResponsiveTooltipContent }
