/**
 * Greyhaven Design System — Shared Component Catalog & Token Utilities
 *
 * Single source of truth consumed by:
 *   - MCP server (mcp/server.ts)
 *   - SKILL.md generator (scripts/generate-skill.ts)
 */

import * as fs from 'fs'
import * as path from 'path'

// ---------------------------------------------------------------------------
// Token utilities
// ---------------------------------------------------------------------------

export const TOKEN_CATEGORIES = ['color', 'typography', 'spacing', 'radii', 'shadows', 'motion'] as const
export type TokenCategory = (typeof TOKEN_CATEGORIES)[number]

export interface FlatToken {
  path: string
  value: unknown
  type?: string
  description?: string
}

export function loadTokenFile(root: string, name: string): Record<string, unknown> {
  const filePath = path.join(root, 'tokens', `${name}.json`)
  return JSON.parse(fs.readFileSync(filePath, 'utf-8'))
}

export function flattenTokens(
  obj: Record<string, unknown>,
  prefix = '',
): FlatToken[] {
  const results: FlatToken[] = []

  for (const [key, val] of Object.entries(obj)) {
    if (key.startsWith('$')) continue
    const currentPath = prefix ? `${prefix}.${key}` : key
    const node = val as Record<string, unknown>

    if (node && typeof node === 'object' && '$value' in node) {
      results.push({
        path: currentPath,
        value: node.$value,
        type: node.$type as string | undefined,
        description: node.$description as string | undefined,
      })
    } else if (node && typeof node === 'object') {
      results.push(...flattenTokens(node, currentPath))
    }
  }

  return results
}

export function getTokens(root: string, category?: string): FlatToken[] {
  if (category && TOKEN_CATEGORIES.includes(category as TokenCategory)) {
    const data = loadTokenFile(root, category)
    return flattenTokens(data)
  }
  const all: FlatToken[] = []
  for (const cat of TOKEN_CATEGORIES) {
    try {
      const data = loadTokenFile(root, cat)
      all.push(...flattenTokens(data))
    } catch {
      // skip missing files
    }
  }
  return all
}

// ---------------------------------------------------------------------------
// Component catalog
// ---------------------------------------------------------------------------

export interface ComponentSpec {
  name: string
  file: string
  category: string
  exports: string[]
  description: string
  props: string
  example: string
}

export const COMPONENT_CATALOG: ComponentSpec[] = [
  // ── Primitives ──────────────────────────────────────────────────────────
  {
    name: 'Button',
    file: 'components/ui/button.tsx',
    category: 'primitives',
    exports: ['Button', 'buttonVariants'],
    description: 'Primary interactive element. 6 variants: default (orange), secondary, outline, ghost, link, destructive. Sizes: default (h-9), sm (h-8), lg (h-10), icon (size-9).',
    props: 'variant?: "default" | "secondary" | "outline" | "ghost" | "link" | "destructive"; size?: "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg"; asChild?: boolean',
    example: '<Button variant="default" size="default">Click me</Button>',
  },
  {
    name: 'Badge',
    file: 'components/ui/badge.tsx',
    category: 'primitives',
    exports: ['Badge', 'badgeVariants'],
    description: 'Status indicator / tag. Variants: default, secondary, muted, outline, destructive, success, warning, info, tag, value, whatsapp, email, telegram, zulip, platform. Sizes: sm (dense data/tables), default (most uses), lg (hero-adjacent, near large type). NEVER override font-size or padding with className — pick a size variant instead. Anything below text-xs (12px) fails accessibility minimums.',
    props: 'variant?: "default" | "secondary" | "muted" | "destructive" | "outline" | "success" | "warning" | "info" | "tag" | "value" | "whatsapp" | "email" | "telegram" | "zulip" | "platform"; size?: "sm" | "default" | "lg"; asChild?: boolean',
    example: '<Badge variant="success">Active</Badge>\n<Badge variant="secondary" size="sm">3 items</Badge>\n<Badge variant="default" size="lg">New feature</Badge>',
  },
  {
    name: 'Input',
    file: 'components/ui/input.tsx',
    category: 'primitives',
    exports: ['Input'],
    description: 'Text input field with focus ring, disabled, and aria-invalid states.',
    props: 'All standard HTML input props',
    example: '<Input type="email" placeholder="you@example.com" />',
  },
  {
    name: 'Textarea',
    file: 'components/ui/textarea.tsx',
    category: 'primitives',
    exports: ['Textarea'],
    description: 'Multi-line text input.',
    props: 'All standard HTML textarea props',
    example: '<Textarea placeholder="Write your message..." />',
  },
  {
    name: 'Label',
    file: 'components/ui/label.tsx',
    category: 'primitives',
    exports: ['Label'],
    description: 'Form label using Radix Label primitive.',
    props: 'All standard HTML label props + Radix Label props',
    example: '<Label htmlFor="email">Email</Label>',
  },
  {
    name: 'Checkbox',
    file: 'components/ui/checkbox.tsx',
    category: 'primitives',
    exports: ['Checkbox'],
    description: 'Checkbox using Radix Checkbox primitive.',
    props: 'checked?: boolean; onCheckedChange?: (checked: boolean) => void',
    example: '<Checkbox id="terms" />',
  },
  {
    name: 'Switch',
    file: 'components/ui/switch.tsx',
    category: 'primitives',
    exports: ['Switch'],
    description: 'Toggle switch using Radix Switch primitive.',
    props: 'checked?: boolean; onCheckedChange?: (checked: boolean) => void',
    example: '<Switch id="dark-mode" />',
  },
  {
    name: 'Select',
    file: 'components/ui/select.tsx',
    category: 'primitives',
    exports: ['Select', 'SelectContent', 'SelectGroup', 'SelectItem', 'SelectLabel', 'SelectTrigger', 'SelectValue'],
    description: 'Dropdown select using Radix Select.',
    props: 'value?: string; onValueChange?: (value: string) => void',
    example: '<Select><SelectTrigger><SelectValue placeholder="Choose..." /></SelectTrigger><SelectContent><SelectItem value="a">Option A</SelectItem></SelectContent></Select>',
  },
  {
    name: 'RadioGroup',
    file: 'components/ui/radio-group.tsx',
    category: 'primitives',
    exports: ['RadioGroup', 'RadioGroupItem'],
    description: 'Radio button group using Radix RadioGroup.',
    props: 'value?: string; onValueChange?: (value: string) => void',
    example: '<RadioGroup defaultValue="a"><RadioGroupItem value="a" /><RadioGroupItem value="b" /></RadioGroup>',
  },
  {
    name: 'Toggle',
    file: 'components/ui/toggle.tsx',
    category: 'primitives',
    exports: ['Toggle', 'toggleVariants'],
    description: 'Toggle button. Variants: default, outline.',
    props: 'variant?: "default" | "outline"; size?: "default" | "sm" | "lg"; pressed?: boolean',
    example: '<Toggle aria-label="Bold"><BoldIcon /></Toggle>',
  },
  {
    name: 'Code',
    file: 'components/ui/code.tsx',
    category: 'primitives',
    exports: ['Code', 'codeVariants'],
    description: 'Inline or block code snippet. Always use this instead of hand-rolling <code>/<pre> styling. Uses bg-muted + border-border so the outline stays visible in both light and dark modes. Block variant auto-wraps in <pre> for whitespace preservation and break-all for long commands.',
    props: 'variant?: "inline" | "block"; language?: string (optional, for future syntax highlighting)',
    example: '<p>Install with <Code>pnpm install</Code>.</p>\n\n<Code variant="block" language="bash">{`pnpm install\npnpm dev`}</Code>',
  },
  // ── Layout ──────────────────────────────────────────────────────────────
  {
    name: 'Card',
    file: 'components/ui/card.tsx',
    category: 'layout',
    exports: ['Card', 'CardHeader', 'CardTitle', 'CardDescription', 'CardAction', 'CardContent', 'CardFooter'],
    description: 'Container with header/content/footer slots. Off-white bg, rounded-xl, subtle shadow.',
    props: 'Standard div props. Compose with CardHeader, CardTitle, CardDescription, CardContent, CardFooter sub-components.',
    example: '<Card><CardHeader><CardTitle>Title</CardTitle><CardDescription>Description</CardDescription></CardHeader><CardContent>Content</CardContent></Card>',
  },
  {
    name: 'Accordion',
    file: 'components/ui/accordion.tsx',
    category: 'layout',
    exports: ['Accordion', 'AccordionItem', 'AccordionTrigger', 'AccordionContent'],
    description: 'Expandable sections using Radix Accordion.',
    props: 'type: "single" | "multiple"; collapsible?: boolean',
    example: '<Accordion type="single" collapsible><AccordionItem value="item-1"><AccordionTrigger>Section 1</AccordionTrigger><AccordionContent>Content</AccordionContent></AccordionItem></Accordion>',
  },
  {
    name: 'Tabs',
    file: 'components/ui/tabs.tsx',
    category: 'layout',
    exports: ['Tabs', 'TabsList', 'TabsTrigger', 'TabsContent'],
    description: 'Tab navigation using Radix Tabs. Pill-style triggers.',
    props: 'value?: string; onValueChange?: (value: string) => void',
    example: '<Tabs defaultValue="tab1"><TabsList><TabsTrigger value="tab1">Tab 1</TabsTrigger></TabsList><TabsContent value="tab1">Content</TabsContent></Tabs>',
  },
  {
    name: 'Separator',
    file: 'components/ui/separator.tsx',
    category: 'layout',
    exports: ['Separator'],
    description: 'Visual divider line. Horizontal or vertical.',
    props: 'orientation?: "horizontal" | "vertical"; decorative?: boolean',
    example: '<Separator />',
  },
  // ── Overlay ─────────────────────────────────────────────────────────────
  {
    name: 'Dialog',
    file: 'components/ui/dialog.tsx',
    category: 'overlay',
    exports: ['Dialog', 'DialogTrigger', 'DialogContent', 'DialogHeader', 'DialogTitle', 'DialogDescription', 'DialogFooter', 'DialogClose'],
    description: 'Modal dialog using Radix Dialog.',
    props: 'open?: boolean; onOpenChange?: (open: boolean) => void',
    example: '<Dialog><DialogTrigger asChild><Button>Open</Button></DialogTrigger><DialogContent><DialogHeader><DialogTitle>Title</DialogTitle></DialogHeader></DialogContent></Dialog>',
  },
  {
    name: 'AlertDialog',
    file: 'components/ui/alert-dialog.tsx',
    category: 'overlay',
    exports: ['AlertDialog', 'AlertDialogTrigger', 'AlertDialogContent', 'AlertDialogHeader', 'AlertDialogTitle', 'AlertDialogDescription', 'AlertDialogFooter', 'AlertDialogAction', 'AlertDialogCancel'],
    description: 'Confirmation dialog requiring user action.',
    props: 'open?: boolean; onOpenChange?: (open: boolean) => void',
    example: '<AlertDialog><AlertDialogTrigger asChild><Button variant="destructive">Delete</Button></AlertDialogTrigger><AlertDialogContent>...</AlertDialogContent></AlertDialog>',
  },
  {
    name: 'Tooltip',
    file: 'components/ui/tooltip.tsx',
    category: 'overlay',
    exports: ['Tooltip', 'TooltipTrigger', 'TooltipContent', 'TooltipProvider'],
    description: 'Tooltip popup (0ms delay) using Radix Tooltip.',
    props: 'Standard Radix Tooltip props',
    example: '<TooltipProvider><Tooltip><TooltipTrigger>Hover me</TooltipTrigger><TooltipContent>Tooltip text</TooltipContent></Tooltip></TooltipProvider>',
  },
  {
    name: 'Popover',
    file: 'components/ui/popover.tsx',
    category: 'overlay',
    exports: ['Popover', 'PopoverTrigger', 'PopoverContent'],
    description: 'Floating content panel using Radix Popover.',
    props: 'open?: boolean; onOpenChange?: (open: boolean) => void',
    example: '<Popover><PopoverTrigger asChild><Button>Open</Button></PopoverTrigger><PopoverContent>Content</PopoverContent></Popover>',
  },
  {
    name: 'Drawer',
    file: 'components/ui/drawer.tsx',
    category: 'overlay',
    exports: ['Drawer', 'DrawerTrigger', 'DrawerContent', 'DrawerHeader', 'DrawerTitle', 'DrawerDescription', 'DrawerFooter', 'DrawerClose'],
    description: 'Bottom sheet drawer using Vaul.',
    props: 'open?: boolean; onOpenChange?: (open: boolean) => void',
    example: '<Drawer><DrawerTrigger asChild><Button>Open</Button></DrawerTrigger><DrawerContent><DrawerHeader><DrawerTitle>Title</DrawerTitle></DrawerHeader></DrawerContent></Drawer>',
  },
  // ── Navigation ──────────────────────────────────────────────────────────
  {
    name: 'Navbar',
    file: 'components/ui/navbar.tsx',
    category: 'navigation',
    exports: ['Navbar', 'NavbarLink', 'navbarVariants'],
    description: 'Top navigation bar. Fixed top, z-50, h-[65px]. Off-white bg (light) / off-black (dark). Font-semibold menu items. Hover: opacity-70 (no bg). Active links: orange (text-primary), full opacity. Variants: solid, transparent, minimal. Logo left, nav center, actions right. Mobile hamburger.',
    props: 'variant?: "solid" | "transparent" | "minimal"; logo?: ReactNode; actions?: ReactNode. NavbarLink: active?: boolean',
    example: '<Navbar variant="solid" logo={<Logo size="sm" />}><NavbarLink href="/" active>Home</NavbarLink><NavbarLink href="/about">About</NavbarLink></Navbar>',
  },
  {
    name: 'Breadcrumb',
    file: 'components/ui/breadcrumb.tsx',
    category: 'navigation',
    exports: ['Breadcrumb', 'BreadcrumbList', 'BreadcrumbItem', 'BreadcrumbLink', 'BreadcrumbPage', 'BreadcrumbSeparator', 'BreadcrumbEllipsis'],
    description: 'Breadcrumb navigation trail.',
    props: 'Standard list composition',
    example: '<Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Current</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>',
  },
  {
    name: 'Pagination',
    file: 'components/ui/pagination.tsx',
    category: 'navigation',
    exports: ['Pagination', 'PaginationContent', 'PaginationItem', 'PaginationLink', 'PaginationPrevious', 'PaginationNext', 'PaginationEllipsis'],
    description: 'Page navigation controls.',
    props: 'Standard list composition with PaginationLink items',
    example: '<Pagination><PaginationContent><PaginationItem><PaginationPrevious href="#" /></PaginationItem><PaginationItem><PaginationLink href="#">1</PaginationLink></PaginationItem><PaginationItem><PaginationNext href="#" /></PaginationItem></PaginationContent></Pagination>',
  },
  // ── Data Display ────────────────────────────────────────────────────────
  {
    name: 'Table',
    file: 'components/ui/table.tsx',
    category: 'data',
    exports: ['Table', 'TableHeader', 'TableBody', 'TableRow', 'TableHead', 'TableCell', 'TableCaption', 'TableFooter'],
    description: 'Data table with header, body, footer.',
    props: 'Standard HTML table element composition',
    example: '<Table><TableHeader><TableRow><TableHead>Name</TableHead></TableRow></TableHeader><TableBody><TableRow><TableCell>John</TableCell></TableRow></TableBody></Table>',
  },
  {
    name: 'Progress',
    file: 'components/ui/progress.tsx',
    category: 'data',
    exports: ['Progress'],
    description: 'Progress bar using Radix Progress.',
    props: 'value?: number (0-100)',
    example: '<Progress value={60} />',
  },
  {
    name: 'Avatar',
    file: 'components/ui/avatar.tsx',
    category: 'data',
    exports: ['Avatar', 'AvatarImage', 'AvatarFallback'],
    description: 'User avatar with image and fallback.',
    props: 'Standard Radix Avatar composition',
    example: '<Avatar><AvatarImage src="/avatar.jpg" /><AvatarFallback>JD</AvatarFallback></Avatar>',
  },
  {
    name: 'Calendar',
    file: 'components/ui/calendar.tsx',
    category: 'data',
    exports: ['Calendar'],
    description: 'Date picker calendar using react-day-picker.',
    props: 'mode?: "single" | "range" | "multiple"; selected?: Date; onSelect?: (date: Date) => void',
    example: '<Calendar mode="single" selected={date} onSelect={setDate} />',
  },
  // ── Feedback ────────────────────────────────────────────────────────────
  {
    name: 'Alert',
    file: 'components/ui/alert.tsx',
    category: 'feedback',
    exports: ['Alert', 'AlertTitle', 'AlertDescription'],
    description: 'Inline alert message. Variants: default, destructive.',
    props: 'variant?: "default" | "destructive"',
    example: '<Alert><AlertTitle>Heads up!</AlertTitle><AlertDescription>This is an alert.</AlertDescription></Alert>',
  },
  {
    name: 'Skeleton',
    file: 'components/ui/skeleton.tsx',
    category: 'feedback',
    exports: ['Skeleton'],
    description: 'Loading placeholder with pulse animation.',
    props: 'Standard div props (set dimensions with className)',
    example: '<Skeleton className="h-4 w-[250px]" />',
  },
  {
    name: 'Spinner',
    file: 'components/ui/spinner.tsx',
    category: 'feedback',
    exports: ['Spinner'],
    description: 'Loading spinner (Loader2Icon with spin animation).',
    props: 'Standard SVG icon props',
    example: '<Spinner />',
  },
  {
    name: 'Empty',
    file: 'components/ui/empty.tsx',
    category: 'feedback',
    exports: ['Empty'],
    description: 'Empty state placeholder with header/media/title/description.',
    props: 'Standard composition with sub-components',
    example: '<Empty><EmptyTitle>No results</EmptyTitle><EmptyDescription>Try a different search</EmptyDescription></Empty>',
  },
  // ── Form ────────────────────────────────────────────────────────────────
  {
    name: 'Form',
    file: 'components/ui/form.tsx',
    category: 'form',
    exports: ['Form', 'FormField', 'FormItem', 'FormLabel', 'FormControl', 'FormDescription', 'FormMessage'],
    description: 'Form wrapper using react-hook-form. Provides field-level validation and error display via Zod.',
    props: 'Wraps react-hook-form useForm return value. FormField takes name + render prop.',
    example: '<Form {...form}><FormField name="email" render={({field}) => (<FormItem><FormLabel>Email</FormLabel><FormControl><Input {...field} /></FormControl><FormMessage /></FormItem>)} /></Form>',
  },
  // ── Composition ─────────────────────────────────────────────────────────
  {
    name: 'Logo',
    file: 'components/ui/logo.tsx',
    category: 'composition',
    exports: ['Logo', 'logoVariants'],
    description: 'Greyhaven logo SVG. Size: sm/md/lg/xl. Variant: color (orange icon + foreground text) or monochrome (all foreground).',
    props: 'size?: "sm" | "md" | "lg" | "xl"; variant?: "color" | "monochrome"',
    example: '<Logo size="md" variant="color" />',
  },
  {
    name: 'Hero',
    file: 'components/ui/hero.tsx',
    category: 'composition',
    exports: ['Hero', 'heroVariants'],
    description: 'Full-width hero section. Variants: centered, left-aligned, split (text + media). Heading in Source Serif, subheading in sans.',
    props: 'variant?: "centered" | "left-aligned" | "split"; background?: "default" | "muted" | "accent" | "dark"; heading: ReactNode; subheading?: ReactNode; actions?: ReactNode; media?: ReactNode',
    example: '<Hero variant="centered" heading="Build something great" subheading="With the Greyhaven Design System" actions={<Button>Get Started</Button>} />',
  },
  {
    name: 'CTASection',
    file: 'components/ui/cta-section.tsx',
    category: 'composition',
    exports: ['CTASection', 'ctaSectionVariants'],
    description: 'Call-to-action section block. Centered or left-aligned, with heading, description, and action buttons.',
    props: 'variant?: "centered" | "left-aligned"; background?: "default" | "muted" | "accent" | "subtle"; heading: ReactNode; description?: ReactNode; actions?: ReactNode',
    example: '<CTASection heading="Ready to start?" description="Join thousands of developers" actions={<Button>Sign up free</Button>} />',
  },
  {
    name: 'Section',
    file: 'components/ui/section.tsx',
    category: 'composition',
    exports: ['Section', 'sectionVariants'],
    description: 'Titled content section with spacing. py-10 internal padding. Colored variants (highlighted, accent) get my-8 vertical margin so they visually detach from adjacent sections; default has no margin so same-bg siblings flow seamlessly.',
    props: 'variant?: "default" | "highlighted" | "accent"; width?: "narrow" | "default" | "wide" | "full"; title?: string; description?: string',
    example: '<Section title="Features" description="What we offer" width="wide">Content</Section>',
  },
  {
    name: 'Footer',
    file: 'components/ui/footer.tsx',
    category: 'composition',
    exports: ['Footer', 'footerVariants'],
    description: 'Page footer. Minimal (single row) or full (multi-column with link groups).',
    props: 'variant?: "minimal" | "full"; logo?: ReactNode; copyright?: ReactNode; linkGroups?: FooterLinkGroup[]; actions?: ReactNode',
    example: '<Footer variant="minimal" copyright="&copy; 2024 Greyhaven" />',
  },
  {
    name: 'PageLayout',
    file: 'components/ui/page-layout.tsx',
    category: 'composition',
    exports: ['PageLayout'],
    description: 'Full page shell composing Navbar + main content + optional sidebar + Footer. Auto-offsets for fixed navbar.',
    props: 'navbar?: ReactNode; sidebar?: ReactNode; footer?: ReactNode',
    example: '<PageLayout navbar={<Navbar />} footer={<Footer />}>Main content</PageLayout>',
  },
]
