"use client"

import { Menu } from 'lucide-react';
import * as React from 'react';

import * as TabsPrimitive from '@radix-ui/react-tabs';

import { useIsMobile } from '../../../hooks';
import { useStoredValue, type StorageType } from '../../../hooks';
import { useAppT } from '@djangocfg/i18n';
import { cn } from '../../../lib/utils';
import { Button } from '../../forms/button';
import { ScrollArea, ScrollBar } from '../../layout/scroll-area';
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '../../overlay/sheet';

// ─────────────────────────────────────────────────────────────────────────
// Tabs Root with Mobile Sheet Support
// ─────────────────────────────────────────────────────────────────────────

export interface TabsProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root> {
  /**
   * Enable mobile sheet mode (automatically shows Sheet on mobile devices)
   * @default false
   */
  mobileSheet?: boolean
  /**
   * Title for mobile sheet header
   * @default "Navigation"
   */
  mobileSheetTitle?: string
  /**
   * Title to display next to burger menu on mobile
   */
  mobileTitleText?: string
  /**
   * Enable sticky positioning (stays at top on scroll)
   * @default false
   */
  sticky?: boolean
  /**
   * When provided, the active tab value is persisted under this key.
   * On mount the last active tab is restored automatically.
   * Works with both controlled (`value`) and uncontrolled (`defaultValue`) modes.
   * In controlled mode the stored value is passed to `defaultValue` on first
   * render; the parent stays in charge after that.
   * @example storageKey="admin-tab"
   */
  storageKey?: string
  /** @default 'local' */
  storageType?: StorageType
}

const Tabs = React.forwardRef<
  React.ElementRef<typeof TabsPrimitive.Root>,
  TabsProps
>(({ mobileSheet = false, mobileSheetTitle, mobileTitleText, sticky = false, storageKey, storageType, children, ...props }, ref) => {
  const t = useAppT()
  const resolvedMobileSheetTitle = mobileSheetTitle ?? t('ui.navigation.title')
  const isMobile = useIsMobile()
  const [open, setOpen] = React.useState(false)

  const [storedTab, setStoredTab] = useStoredValue<string>(
    storageKey,
    // seed: prefer defaultValue prop, then controlled value, then empty
    (props.defaultValue as string | undefined) ?? (props.value as string | undefined) ?? '',
    storageKey ? { storage: storageType ?? 'local' } : undefined,
  );

  // Wrap onValueChange to persist tab changes
  const handleValueChange = React.useCallback(
    (newValue: string) => {
      if (storageKey) setStoredTab(newValue);
      props.onValueChange?.(newValue);
    },
    [storageKey, setStoredTab, props.onValueChange],
  );

  // Build enhanced props: inject stored defaultValue when no value/defaultValue given
  const tabsProps = {
    ...props,
    onValueChange: storageKey ? handleValueChange : props.onValueChange,
    // Only inject defaultValue when: storageKey set, no controlled value, storedTab non-empty
    ...(storageKey && props.value === undefined && storedTab
      ? { defaultValue: storedTab }
      : {}),
  };

  // If mobile sheet mode is disabled, render normal tabs
  if (!mobileSheet || !isMobile) {
    // If sticky is enabled for desktop, wrap TabsList in sticky container
    if (sticky) {
      const childrenArray = React.Children.toArray(children)
      const tabsList = childrenArray.find(
        (child) => React.isValidElement(child) && child.type === TabsList
      )
      const tabsContent = childrenArray.filter(
        (child) => React.isValidElement(child) && child.type === TabsContent
      )

      return (
        <TabsPrimitive.Root ref={ref} {...tabsProps}>
          <div className="sticky top-0 z-40 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 mb-4">
            {tabsList}
          </div>
          {tabsContent}
        </TabsPrimitive.Root>
      )
    }

    return (
      <TabsPrimitive.Root ref={ref} {...tabsProps}>
        {children}
      </TabsPrimitive.Root>
    )
  }

  // Extract TabsList and TabsContent from children
  const childrenArray = React.Children.toArray(children)
  const tabsList = childrenArray.find(
    (child) => React.isValidElement(child) && child.type === TabsList
  )
  const tabsContent = childrenArray.filter(
    (child) => React.isValidElement(child) && child.type === TabsContent
  )

  // Extract triggers from TabsList children
  const triggers = React.isValidElement(tabsList)
    ? React.Children.toArray((tabsList.props as any).children)
    : []

  // Mobile Sheet Navigation
  return (
    <TabsPrimitive.Root ref={ref} {...tabsProps}>
      <div className={cn(
        "w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 mb-4",
        sticky && "sticky top-0 z-40"
      )}>
        <div className="container mx-auto flex items-center justify-between h-14 px-4">
          {/* Title */}
          {mobileTitleText && (
            <h1 className="text-lg font-semibold">{mobileTitleText}</h1>
          )}

          {/* Menu Button */}
          <Sheet open={open} onOpenChange={setOpen}>
            <SheetTrigger asChild>
              <Button variant="ghost" size="icon" className={mobileTitleText ? "" : "ml-auto"}>
                <Menu className="h-5 w-5" />
              </Button>
            </SheetTrigger>
            <SheetContent side="right" className="w-[280px] sm:w-[350px]">
              <SheetHeader>
                <SheetTitle>{resolvedMobileSheetTitle}</SheetTitle>
              </SheetHeader>
              <nav className="flex flex-col gap-2 mt-6">
                <TabsPrimitive.List className="flex flex-col gap-2">
                  {triggers.map((trigger, index) => {
                    if (!React.isValidElement(trigger)) return null

                    // Clone trigger and wrap in mobile-friendly container
                    const triggerProps = (trigger as any).props || {};
                    return React.cloneElement(trigger as React.ReactElement, {
                      key: index,
                      onClick: (e: React.MouseEvent) => {
                        setOpen(false)
                        triggerProps.onClick?.(e)
                      },
                      className: cn(
                        "flex items-center gap-3 px-3 py-2 rounded-[var(--radius-sm)] transition-colors justify-start w-full",
                        "data-[state=active]:bg-primary data-[state=active]:text-primary-foreground",
                        "hover:bg-muted",
                        triggerProps.className
                      ),
                    } as any)
                  })}
                </TabsPrimitive.List>
              </nav>
            </SheetContent>
          </Sheet>
        </div>
      </div>
      {tabsContent}
    </TabsPrimitive.Root>
  )
})
Tabs.displayName = "Tabs"

// ─────────────────────────────────────────────────────────────────────────
// Tabs variant context — lets TabsTrigger inherit variant from TabsList
// ─────────────────────────────────────────────────────────────────────────

type TabsVariant = 'default' | 'underline'
const TabsVariantContext = React.createContext<TabsVariant>('default')

const TabsList = React.forwardRef<
  React.ElementRef<typeof TabsPrimitive.List>,
  React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> & {
    /**
     * Visual variant.
     * - `default` — pill/card style (bg-muted container)
     * - `underline` — borderless, underline indicator on active tab
     * @default 'default'
     */
    variant?: TabsVariant
    /**
     * Full width mode - tabs will stretch equally to fill the container
     * @default false
     */
    fullWidth?: boolean
    /**
     * Enable horizontal scrolling when tabs overflow
     * @default false
     */
    scrollable?: boolean
  }
>(({ className, variant = 'default', fullWidth = false, scrollable = false, ...props }, ref) => {
  const isUnderline = variant === 'underline'

  const listCls = cn(
    isUnderline
      ? "inline-flex items-end gap-0 bg-transparent p-0 h-auto rounded-none"
      : "inline-flex h-9 items-center justify-center rounded-[var(--radius)] bg-muted p-1 text-muted-foreground",
    fullWidth && "w-full flex",
    className
  )

  const list = (
    <TabsPrimitive.List ref={ref} className={listCls} {...props} />
  )

  // For underline variant — native overflow-x-auto, full-width border via absolute element
  const wrapped = isUnderline ? (
    <div
      className={cn("relative w-full", scrollable && "overflow-x-auto")}
      style={scrollable ? { scrollbarWidth: 'none', msOverflowStyle: 'none' } as React.CSSProperties : undefined}
    >
      <div className="absolute bottom-0 left-0 right-0 h-px bg-border" />
      {list}
    </div>
  ) : scrollable ? (
    <ScrollArea className="w-full whitespace-nowrap">
      {list}
      <ScrollBar orientation="horizontal" />
    </ScrollArea>
  ) : list

  return (
    <TabsVariantContext.Provider value={variant}>
      {wrapped}
    </TabsVariantContext.Provider>
  )
})
TabsList.displayName = TabsPrimitive.List.displayName

const TabsTrigger = React.forwardRef<
  React.ElementRef<typeof TabsPrimitive.Trigger>,
  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> & {
    /**
     * Makes the trigger take equal space (use with fullWidth TabsList)
     * @default false
     */
    flexEqual?: boolean
    key?: React.Key
  }
>(({ className, flexEqual = false, ...props }, ref) => {
  const variant = React.useContext(TabsVariantContext)
  const isUnderline = variant === 'underline'

  return (
    <TabsPrimitive.Trigger
      ref={ref}
      className={cn(
        isUnderline
          ? [
              "relative z-10 rounded-none bg-transparent shadow-none whitespace-nowrap",
              "px-3 py-2.5 mb-[-1px]",
              "text-sm font-medium text-muted-foreground/60",
              "border-b-2 border-transparent",
              "transition-all duration-150",
              "hover:text-foreground",
              "focus-visible:outline-none",
              "disabled:pointer-events-none disabled:opacity-50",
              "data-[state=active]:text-foreground data-[state=active]:font-semibold",
              "data-[state=active]:border-foreground data-[state=active]:shadow-none",
            ].join(" ")
          : [
              "inline-flex items-center justify-center whitespace-nowrap rounded-[var(--radius-sm)] px-3 py-1",
              "text-sm font-medium transition-all",
              "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
              "disabled:pointer-events-none disabled:opacity-50",
              "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
            ].join(" "),
        flexEqual && "flex-1",
        className
      )}
      {...props}
    />
  )
})
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName

const TabsContent = React.forwardRef<
  React.ElementRef<typeof TabsPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> & { key?: React.Key }
>(({ className, ...props }, ref) => (
  <TabsPrimitive.Content
    ref={ref}
    className={cn(
      "mt-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
      className
    )}
    {...props}
  />
))
TabsContent.displayName = TabsPrimitive.Content.displayName

export { Tabs, TabsList, TabsTrigger, TabsContent }
