"use client"

import * as React from "react"
import { cn } from "@/shared/utils/utils"

interface TabsContextValue {
  value: string
  onValueChange: (value: string) => void
}

const TabsContext = React.createContext<TabsContextValue | null>(null)

function useTabsContext() {
  const context = React.useContext(TabsContext)
  if (!context) {
    throw new Error("Tabs components must be used within a Tabs provider")
  }
  return context
}

interface TabsListContextValue {
  variant?: "default" | "line"
}

const TabsListContext = React.createContext<TabsListContextValue>({ variant: "default" })

interface TabsProps extends React.HTMLAttributes<HTMLDivElement> {
  defaultValue?: string
  value?: string
  onValueChange?: (value: string) => void
  children: React.ReactNode
}

function Tabs({
  defaultValue,
  value: controlledValue,
  onValueChange,
  className,
  children,
  ...props
}: TabsProps) {
  const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue || "")
  const isControlled = controlledValue !== undefined
  const currentValue = isControlled ? controlledValue : uncontrolledValue

  const handleValueChange = React.useCallback(
    (newValue: string) => {
      if (!isControlled) {
        setUncontrolledValue(newValue)
      }
      onValueChange?.(newValue)
    },
    [isControlled, onValueChange]
  )

  return (
    <TabsContext.Provider value={{ value: currentValue, onValueChange: handleValueChange }}>
      <div data-slot="tabs" className={cn("flex flex-col gap-2", className)} {...props}>
        {children}
      </div>
    </TabsContext.Provider>
  )
}

interface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {
  variant?: "default" | "line"
}

function TabsList({ className, variant = "default", children, ...props }: TabsListProps) {
  return (
    <TabsListContext.Provider value={{ variant }}>
      <div
        data-slot="tabs-list"
        data-variant={variant}
        className={cn(
          variant === "line"
            ? "inline-flex h-10 items-center justify-start border-b border-border/80 text-muted-foreground w-full gap-1 p-0 bg-transparent self-start"
            : "inline-flex h-10 items-center justify-start rounded-lg bg-muted p-1 text-muted-foreground w-fit max-w-full self-start",
          className
        )}
        {...props}
      >
        {children}
      </div>
    </TabsListContext.Provider>
  )
}

interface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  value: string
}

function TabsTrigger({ className, value, children, ...props }: TabsTriggerProps) {
  const { value: selectedValue, onValueChange } = useTabsContext()
  const { variant } = React.useContext(TabsListContext)
  const isSelected = selectedValue === value

  return (
    <button
      type="button"
      role="tab"
      aria-selected={isSelected}
      data-state={isSelected ? "active" : "inactive"}
      onClick={() => onValueChange(value)}
      className={cn(
        "inline-flex items-center justify-center whitespace-nowrap text-xs font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 cursor-pointer",
        variant === "line"
          ? isSelected
            ? "bg-background text-foreground border border-border/80 border-b-background rounded-t-lg -mb-px relative z-10 px-4 py-2 font-semibold shadow-2xs"
            : "bg-transparent text-muted-foreground hover:text-foreground border-b border-transparent px-4 py-2 font-medium"
          : isSelected
            ? "bg-background text-foreground shadow-xs font-semibold rounded-md px-3 py-1.5"
            : "hover:bg-background/50 hover:text-foreground rounded-md px-3 py-1.5",
        className
      )}
      {...props}
    >
      {children}
    </button>
  )
}

interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {
  value: string
}

function TabsContent({ className, value, children, ...props }: TabsContentProps) {
  const { value: selectedValue } = useTabsContext()
  const isSelected = selectedValue === value

  if (!isSelected) return null

  return (
    <div
      role="tabpanel"
      data-state={isSelected ? "active" : "inactive"}
      className={cn(
        "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
        className
      )}
      {...props}
    >
      {children}
    </div>
  )
}

export { Tabs, TabsList, TabsTrigger, TabsContent }
