import * as React from 'react'
import { Command as CommandPrimitive } from 'cmdk'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { cn } from '../lib/cn'

export interface CommandItem {
  id: string
  label: string
  icon?: React.ReactNode
  onSelect: () => void
}

export interface CommandGroup {
  label: string
  items: CommandItem[]
}

export interface CommandProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  placeholder?: string
  groups: CommandGroup[]
  onSearch?: (query: string) => void // async search
}

/**
 * Command palette built on cmdk, mounted inside a Radix Dialog for focus
 * trapping + Esc-to-close. Used by global search / command palette.
 */
export function Command({ open, onOpenChange, placeholder, groups, onSearch }: CommandProps) {
  return (
    <DialogPrimitive.Root open={open} onOpenChange={onOpenChange}>
      <DialogPrimitive.Portal>
        <DialogPrimitive.Overlay className="fixed inset-0 z-50 bg-ink/40 motion-reduce:animate-none" />
        <DialogPrimitive.Content
          className={cn(
            'fixed start-1/2 top-24 z-50 w-full max-w-screen-sm -translate-x-1/2 rtl:translate-x-1/2',
            'overflow-hidden rounded border border-line bg-surface text-ink shadow focus:outline-none',
          )}
        >
          <DialogPrimitive.Title className="sr-only">Command palette</DialogPrimitive.Title>
          <CommandPrimitive shouldFilter={!onSearch}>
            <CommandPrimitive.Input
              placeholder={placeholder ?? 'Type a command or search…'}
              onValueChange={onSearch}
              className="h-12 w-full border-b border-line bg-transparent px-4 text-body-1 text-ink outline-none placeholder:text-ink-faint"
            />
            <CommandPrimitive.List className="max-h-80 overflow-auto p-2">
              <CommandPrimitive.Empty className="px-2 py-4 text-body-2 text-ink-faint">
                No results found.
              </CommandPrimitive.Empty>
              {groups.map((group) => (
                <CommandPrimitive.Group
                  key={group.label}
                  heading={group.label}
                  className="text-meta text-ink-faint [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-0.5"
                >
                  {group.items.map((item) => (
                    <CommandPrimitive.Item
                      key={item.id}
                      value={`${group.label} ${item.label}`}
                      onSelect={() => {
                        item.onSelect()
                        onOpenChange(false)
                      }}
                      className={cn(
                        'flex h-8 cursor-default select-none items-center gap-2 rounded px-2 text-body-2 text-ink',
                        'data-[selected=true]:bg-hover',
                      )}
                    >
                      {item.icon ? <span className="shrink-0">{item.icon}</span> : null}
                      {item.label}
                    </CommandPrimitive.Item>
                  ))}
                </CommandPrimitive.Group>
              ))}
            </CommandPrimitive.List>
          </CommandPrimitive>
        </DialogPrimitive.Content>
      </DialogPrimitive.Portal>
    </DialogPrimitive.Root>
  )
}
