// Universal Component Fact (UCF) types.
//
// Verbatim port of `apps/cloud/docs/canonical-primitive-map/01-architecture.md`
// §7.1. The classifier reads UCFs; framework adapters write UCFs. Diverging from
// the spec here is a contract break — update the spec first.

import type { FactLocation } from "@fragments-sdk/core";
import type { StoryComponentImport, StoryFactsStory } from "../storybook/types.js";

export type Framework = "react" | "vue" | "svelte" | "angular" | "solid" | "preact" | "lit";

export type DefinitionKind = "function" | "class" | "sfc" | "directive" | "wrapper";

export type StyleSystem =
  | "tailwind"
  | "cssModules"
  | "styledComponents"
  | "cssInJs"
  | "plainCss"
  | "sass"
  | "unknown";

export type ControlledFlag = boolean | "mixed" | "unknown";

export type PropSchemaConfidence = "exact" | "partial" | "unknown";

export interface ImportRecord {
  moduleSpecifier: string;
  resolvedPackage?: string;
  importedNames: ReadonlyArray<{
    imported: string;
    local: string;
  }>;
}

export interface ExportRecord {
  exportedAs: string;
  isPrimary: boolean;
  localName?: string;
  isDefault?: boolean;
  fromBarrel?: boolean;
}

export interface RootElementFact {
  tag: string;
  attrs: Record<string, string | true>;
  loc: FactLocation;
  inputType?: string;
  conditionalGuard?: string;
}

export interface PropFact {
  name: string;
  typeText: string;
  loc: FactLocation;
  optional: boolean;
  hasDefault: boolean;
  defaultValueText?: string;
  jsdoc?: string;
  isUnion: boolean;
  unionMembers?: ReadonlyArray<string>;
  schemaConfidence?: PropSchemaConfidence;
}

export interface EventFact {
  name: string;
  payloadTypeText?: string;
}

export interface SlotFact {
  name: string;
  scoped: boolean;
}

export interface CallSiteSample {
  filePath: string;
  jsxText: string;
  framework: Framework;
}

export interface StoryEvidence {
  source: "storybook";
  title?: string;
  componentImport: StoryComponentImport;
  storyCount: number;
  storyRefs: ReadonlyArray<string>;
  storyNames: ReadonlyArray<string>;
  storyFilePaths: ReadonlyArray<string>;
  tags: ReadonlyArray<string>;
  metaArgs: Record<string, unknown>;
  stories: ReadonlyArray<StoryFactsStory>;
  autodocsDescription?: string;
}

export interface UniversalComponentFact {
  // Identity
  id: string;
  filePath: string;
  componentName: string;
  framework: Framework;
  sourceCommit: string;
  capturedAt: string;
  adapterVersion: string;

  // Definition shape
  definitionKind: DefinitionKind;
  wrappedBy: ReadonlyArray<string>;

  // Module graph
  imports: ReadonlyArray<ImportRecord>;
  exports: ReadonlyArray<ExportRecord>;
  exportedFromBarrel: boolean;

  // Render facts
  rootElements: ReadonlyArray<RootElementFact>;
  rootElementsTruncated: boolean;

  // Native semantics
  ariaRoles: ReadonlyArray<string>;
  ariaAttributes: Record<string, string | true>;

  // API surface
  props: ReadonlyArray<PropFact>;
  events: ReadonlyArray<EventFact>;
  slots: ReadonlyArray<SlotFact>;

  // Behavior hints
  hasInternalState: boolean;
  hasEffects: boolean;
  isControlled: ControlledFlag;
  compoundChildren: ReadonlyArray<string>;

  // Style system
  styleSystem: StyleSystem;
  classNamesUsed: ReadonlyArray<string>;

  // Source-level hints
  jsdocDescription?: string;
  fileHeaderComment?: string;

  // Usage hints (cross-file, optional)
  callSites?: ReadonlyArray<CallSiteSample>;
  importCount?: number;
  storyEvidence?: ReadonlyArray<StoryEvidence>;
}
