import { z } from "zod/v4";
import { accessSync } from "node:fs";
import { resolve, join } from "node:path";
import { type ComponentEntry, type ComponentMeta, toExportPath } from "./component-imports.js";
import { DialogRootPropsSchema, DialogContentPropsSchema, DialogMeta } from "../../core/src/components/dialog/dialog.props.js";
import { ButtonPropsSchema, ButtonMeta } from "../../core/src/components/button/button.props.js";
import { BadgePropsSchema, BadgeMeta } from "../../core/src/components/badge/badge.props.js";
import { AlertPropsSchema, AlertMeta } from "../../core/src/components/alert/alert.props.js";
import { LinkPropsSchema, LinkMeta } from "../../core/src/components/link/link.props.js";
import { SelectRootPropsSchema, SelectItemPropsSchema, SelectMeta } from "../../core/src/components/select/select.props.js";
import { TogglePropsSchema, ToggleMeta } from "../../core/src/components/toggle/toggle.props.js";
import { ComboboxRootPropsSchema, ComboboxItemPropsSchema, ComboboxMeta } from "../../core/src/components/combobox/combobox.props.js";
import { DropdownMenuRootPropsSchema, DropdownMenuItemPropsSchema, DropdownMenuMeta } from "../../core/src/components/dropdown-menu/dropdown-menu.props.js";
import { TextFieldRootPropsSchema, TextFieldMeta } from "../../core/src/components/text-field/text-field.props.js";
import { ListboxRootPropsSchema, ListboxItemPropsSchema, ListboxMeta } from "../../core/src/components/listbox/listbox.props.js";
import { CheckboxRootPropsSchema, CheckboxMeta } from "../../core/src/components/checkbox/checkbox.props.js";
import { SwitchRootPropsSchema, SwitchMeta } from "../../core/src/components/switch/switch.props.js";
import { TooltipRootPropsSchema, TooltipMeta } from "../../core/src/components/tooltip/tooltip.props.js";
import { PopoverRootPropsSchema, PopoverMeta } from "../../core/src/components/popover/popover.props.js";
import { RadioGroupRootPropsSchema, RadioGroupItemPropsSchema, RadioGroupMeta } from "../../core/src/components/radio-group/radio-group.props.js";
import { HoverCardRootPropsSchema, HoverCardMeta } from "../../core/src/components/hover-card/hover-card.props.js";
import { DrawerRootPropsSchema, DrawerMeta } from "../../core/src/components/drawer/drawer.props.js";
import { ToastRegionPropsSchema, ToastMeta } from "../../core/src/components/toast/toast.props.js";
import { SkeletonPropsSchema, SkeletonMeta } from "../../core/src/components/skeleton/skeleton.props.js";
import { SliderRootPropsSchema, SliderMeta } from "../../core/src/components/slider/slider.props.js";
import { NumberFieldRootPropsSchema as NumFieldRootSchema, NumberFieldMeta as NumFieldMeta } from "../../core/src/components/number-field/number-field.props.js";
import { ToggleGroupRootPropsSchema, ToggleGroupItemPropsSchema, ToggleGroupMeta } from "../../core/src/components/toggle-group/toggle-group.props.js";
import { ProgressRootPropsSchema, ProgressMeta } from "../../core/src/components/progress/progress.props.js";
import { CollapsibleRootPropsSchema, CollapsibleMeta } from "../../core/src/components/collapsible/collapsible.props.js";
import { AlertDialogRootPropsSchema, AlertDialogMeta } from "../../core/src/components/alert-dialog/alert-dialog.props.js";
import { BreadcrumbsRootPropsSchema, BreadcrumbsMeta } from "../../core/src/components/breadcrumbs/breadcrumbs.props.js";
import { TabsRootPropsSchema, TabsMeta } from "../../core/src/components/tabs/tabs.props.js";
import { AccordionRootPropsSchema, AccordionItemPropsSchema, AccordionMeta } from "../../core/src/components/accordion/accordion.props.js";
import { CardPropsSchema, CardMeta } from "../../core/src/components/card/card.props.js";
import { AvatarRootPropsSchema, AvatarImagePropsSchema, AvatarMeta } from "../../core/src/components/avatar/avatar.props.js";
import { NavigationMenuRootPropsSchema, NavigationMenuMeta } from "../../core/src/components/navigation-menu/navigation-menu.props.js";
import { CommandPaletteRootPropsSchema, CommandPaletteMeta } from "../../core/src/components/command-palette/command-palette.props.js";
import { FormRootPropsSchema, FormFieldPropsSchema, FormMeta } from "../../core/src/components/form/form.props.js";
import { CalendarRootPropsSchema, CalendarMeta } from "../../core/src/components/calendar/calendar.props.js";
import { WizardRootPropsSchema, WizardStepPropsSchema, WizardMeta } from "../../core/src/components/wizard/wizard.props.js";
import { DataTableRootPropsSchema, DataTableMeta } from "../../core/src/components/data-table/data-table.props.js";
import { VirtualListRootPropsSchema, VirtualListMeta } from "../../core/src/components/virtual-list/virtual-list.props.js";
import { DatePickerRootPropsSchema, DatePickerMeta } from "../../core/src/components/date-picker/date-picker.props.js";
import { SeparatorPropsSchema, SeparatorMeta } from "../../core/src/components/separator/separator.props.js";
import { PaginationRootPropsSchema, PaginationMeta } from "../../core/src/components/pagination/pagination.props.js";

export interface RegisteredComponent { meta: ComponentMeta; schemas: Record<string, unknown>; jsonSchemas: Record<string, unknown>; hasStyledVersion: boolean; exportPath: string; }
export interface SearchResult extends RegisteredComponent { score: number; }

function buildEntries(): ComponentEntry[] {
  const ep = toExportPath;
  const out: ComponentEntry[] = [];
  out[out.length] = { exportPath: ep("Dialog"), meta: DialogMeta, schemas: { dialogRoot: DialogRootPropsSchema, dialogContent: DialogContentPropsSchema } };
  out[out.length] = { exportPath: ep("Button"), meta: ButtonMeta, schemas: { button: ButtonPropsSchema } };
  out[out.length] = { exportPath: ep("Badge"), meta: BadgeMeta, schemas: { badge: BadgePropsSchema } };
  out[out.length] = { exportPath: ep("Alert"), meta: AlertMeta, schemas: { alert: AlertPropsSchema } };
  out[out.length] = { exportPath: ep("Link"), meta: LinkMeta, schemas: { link: LinkPropsSchema } };
  out[out.length] = { exportPath: ep("Select"), meta: SelectMeta, schemas: { selectRoot: SelectRootPropsSchema, selectItem: SelectItemPropsSchema } };
  out[out.length] = { exportPath: ep("Toggle"), meta: ToggleMeta, schemas: { toggle: TogglePropsSchema } };
  out[out.length] = { exportPath: ep("Combobox"), meta: ComboboxMeta, schemas: { comboboxRoot: ComboboxRootPropsSchema, comboboxItem: ComboboxItemPropsSchema } };
  out[out.length] = { exportPath: ep("DropdownMenu"), meta: DropdownMenuMeta, schemas: { dropdownMenuRoot: DropdownMenuRootPropsSchema, dropdownMenuItem: DropdownMenuItemPropsSchema } };
  out[out.length] = { exportPath: ep("TextField"), meta: TextFieldMeta, schemas: { textFieldRoot: TextFieldRootPropsSchema } };
  out[out.length] = { exportPath: ep("Listbox"), meta: ListboxMeta, schemas: { listboxRoot: ListboxRootPropsSchema, listboxItem: ListboxItemPropsSchema } };
  out[out.length] = { exportPath: ep("Checkbox"), meta: CheckboxMeta, schemas: { checkboxRoot: CheckboxRootPropsSchema } };
  out[out.length] = { exportPath: ep("Switch"), meta: SwitchMeta, schemas: { switchRoot: SwitchRootPropsSchema } };
  out[out.length] = { exportPath: ep("Tooltip"), meta: TooltipMeta, schemas: { tooltipRoot: TooltipRootPropsSchema } };
  out[out.length] = { exportPath: ep("Popover"), meta: PopoverMeta, schemas: { popoverRoot: PopoverRootPropsSchema } };
  out[out.length] = { exportPath: ep("RadioGroup"), meta: RadioGroupMeta, schemas: { radioGroupRoot: RadioGroupRootPropsSchema, radioGroupItem: RadioGroupItemPropsSchema } };
  out[out.length] = { exportPath: ep("HoverCard"), meta: HoverCardMeta, schemas: { hoverCardRoot: HoverCardRootPropsSchema } };
  out[out.length] = { exportPath: ep("Drawer"), meta: DrawerMeta, schemas: { drawerRoot: DrawerRootPropsSchema } };
  out[out.length] = { exportPath: ep("Toast"), meta: ToastMeta, schemas: { toastRegion: ToastRegionPropsSchema } };
  out[out.length] = { exportPath: ep("Skeleton"), meta: SkeletonMeta, schemas: { skeleton: SkeletonPropsSchema } };
  out[out.length] = { exportPath: ep("Slider"), meta: SliderMeta, schemas: { sliderRoot: SliderRootPropsSchema } };
  out[out.length] = { exportPath: ep("NumField"), meta: NumFieldMeta, schemas: { numFieldRoot: NumFieldRootSchema } };
  out[out.length] = { exportPath: ep("ToggleGroup"), meta: ToggleGroupMeta, schemas: { toggleGroupRoot: ToggleGroupRootPropsSchema, toggleGroupItem: ToggleGroupItemPropsSchema } };
  out[out.length] = { exportPath: ep("Progress"), meta: ProgressMeta, schemas: { progressRoot: ProgressRootPropsSchema } };
  out[out.length] = { exportPath: ep("Collapsible"), meta: CollapsibleMeta, schemas: { collapsibleRoot: CollapsibleRootPropsSchema } };
  out[out.length] = { exportPath: ep("AlertDialog"), meta: AlertDialogMeta, schemas: { alertDialogRoot: AlertDialogRootPropsSchema } };
  out[out.length] = { exportPath: ep("Breadcrumbs"), meta: BreadcrumbsMeta, schemas: { breadcrumbsRoot: BreadcrumbsRootPropsSchema } };
  out[out.length] = { exportPath: ep("Tabs"), meta: TabsMeta, schemas: { tabsRoot: TabsRootPropsSchema } };
  out[out.length] = { exportPath: ep("Accordion"), meta: AccordionMeta, schemas: { accordionRoot: AccordionRootPropsSchema, accordionItem: AccordionItemPropsSchema } };
  out[out.length] = { exportPath: ep("Card"), meta: CardMeta, schemas: { card: CardPropsSchema } };
  out[out.length] = { exportPath: ep("Avatar"), meta: AvatarMeta, schemas: { avatarRoot: AvatarRootPropsSchema, avatarImage: AvatarImagePropsSchema } };
  out[out.length] = { exportPath: ep("NavigationMenu"), meta: NavigationMenuMeta, schemas: { navigationMenuRoot: NavigationMenuRootPropsSchema } };
  out[out.length] = { exportPath: ep("CommandPalette"), meta: CommandPaletteMeta, schemas: { commandPaletteRoot: CommandPaletteRootPropsSchema } };
  out[out.length] = { exportPath: ep("Form"), meta: FormMeta, schemas: { formRoot: FormRootPropsSchema, formField: FormFieldPropsSchema } };
  out[out.length] = { exportPath: ep("Calendar"), meta: CalendarMeta, schemas: { calendarRoot: CalendarRootPropsSchema } };
  out[out.length] = { exportPath: ep("Wizard"), meta: WizardMeta, schemas: { wizardRoot: WizardRootPropsSchema, wizardStep: WizardStepPropsSchema } };
  out[out.length] = { exportPath: ep("DataTable"), meta: DataTableMeta, schemas: { dataTableRoot: DataTableRootPropsSchema } };
  out[out.length] = { exportPath: ep("VirtualList"), meta: VirtualListMeta, schemas: { virtualListRoot: VirtualListRootPropsSchema } };
  out[out.length] = { exportPath: ep("DatePicker"), meta: DatePickerMeta, schemas: { datePickerRoot: DatePickerRootPropsSchema } };
  out[out.length] = { exportPath: ep("Separator"), meta: SeparatorMeta, schemas: { separator: SeparatorPropsSchema } };
  out[out.length] = { exportPath: ep("Pagination"), meta: PaginationMeta, schemas: { paginationRoot: PaginationRootPropsSchema } };
  return out;
}
export const COMPONENT_ENTRIES: ComponentEntry[] = buildEntries();

function toJsonSchema(schema: unknown): unknown {
  try {
    return z.toJsonSchema(schema as z.ZodType);
  } catch {
    return { type: "object" };
  }
}

function styledFileExists(name: string): boolean {
  const kebab = name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
  const styledPath = join(resolve(import.meta.dirname, "../../registry/src/components"), `${kebab}.tsx`);
  try {
    accessSync(styledPath);
    return true;
  } catch {
    return false;
  }
}

function toRegistered(entry: ComponentEntry): RegisteredComponent {
  const jsonSchemas: Record<string, unknown> = {};
  for (const [key, schema] of Object.entries(entry.schemas)) {
    jsonSchemas[key] = toJsonSchema(schema);
  }
  return { meta: entry.meta, schemas: entry.schemas, jsonSchemas, hasStyledVersion: styledFileExists(entry.meta.name), exportPath: entry.exportPath };
}

/** Registry of all PettyUI components with search, lookup, and JSON Schema conversion. */
export class ComponentRegistry {
  private readonly components: Map<string, RegisteredComponent>;

  constructor() {
    this.components = new Map();
    this.loadComponents();
  }

  private loadComponents(): void {
    for (const entry of COMPONENT_ENTRIES) {
      this.components.set(entry.meta.name.toLowerCase(), toRegistered(entry));
    }
  }

  /** Returns all registered components. */
  listComponents(): RegisteredComponent[] {
    return Array.from(this.components.values());
  }

  /** Finds a component by name (case-insensitive). Returns undefined if not found. */
  getComponent(name: string): RegisteredComponent | undefined {
    return this.components.get(name.toLowerCase());
  }

  /** Searches components by name and description, returning ranked results. */
  search(query: string): SearchResult[] {
    const terms = query.toLowerCase().split(/\s+/);
    const results: SearchResult[] = [];
    for (const comp of this.components.values()) {
      const score = this.scoreComponent(comp, terms);
      if (score > 0) results.push({ ...comp, score });
    }
    return results.sort((a, b) => b.score - a.score);
  }

  private scoreComponent(comp: RegisteredComponent, terms: string[]): number {
    const name = comp.meta.name.toLowerCase();
    const text = `${name} ${comp.meta.description.toLowerCase()}`;
    let score = 0;
    for (const term of terms) {
      if (text.includes(term)) score += 1;
      if (name === term) score += 3;
      if (name.includes(term)) score += 1;
    }
    return score;
  }
}
