export type ModelIngestProviderKind = "embedded-open" | "autodesk-aps" | "none";

export type ModelIngestCapabilityStatus =
  | "available"
  | "missing"
  | "unsupported"
  | "degraded"
  | "failed";

export type ModelIngestRunStatus =
  | "indexed"
  | "partial"
  | "failed";

export type ModelIngestArtifactKind =
  | "manifest"
  | "raw-elements"
  | "raw-quantities"
  | "raw-bom"
  | "geometry-manifest"
  | "adapter-log";

export interface ModelIngestFeatureSet {
  geometry: boolean;
  properties: boolean;
  quantities: boolean;
  estimateLens: boolean;
  rawArtifacts: boolean;
  requiresCloud?: boolean;
}

export interface ModelIngestCapability {
  adapterId: string;
  adapterVersion: string;
  provider: ModelIngestProviderKind;
  formats: string[];
  status: ModelIngestCapabilityStatus;
  features: ModelIngestFeatureSet;
  message?: string;
  missingConfigKeys?: string[];
  metadata?: Record<string, unknown>;
}

export interface ModelIngestSourceProvenance {
  sourceKind: "source_document" | "file_node";
  sourceId: string;
  projectId: string;
  fileName: string;
  fileType?: string | null;
  format: string;
  storagePath?: string | null;
  sourceChecksum: string;
  sourceSize: number;
  adapterId: string;
  adapterVersion: string;
  provider: ModelIngestProviderKind;
  generatedAt: string;
  method: string;
  confidence: number;
}

export interface ModelIngestArtifact {
  id: string;
  kind: ModelIngestArtifactKind;
  path: string;
  mediaType: string;
  checksum?: string;
  size?: number;
  description?: string;
  metadata?: Record<string, unknown>;
}

export interface ModelGeometryArtifact {
  id: string;
  format: "native" | "dae" | "glb" | "gltf" | "obj" | "stl" | "mesh-json";
  path?: string;
  checksum?: string;
  meshRefs: string[];
  bbox?: unknown;
  units?: string;
  metadata?: Record<string, unknown>;
}

export interface CanonicalModelElement {
  id: string;
  externalId: string;
  name: string;
  elementClass: string;
  elementType?: string;
  system?: string;
  level?: string;
  material?: string;
  bbox?: unknown;
  geometryRef?: string;
  estimateRelevant?: boolean;
  /** Construction classification keyed by standard. Same shape as
   *  WorksheetItem.classification (see classification-utils.ts) — keys:
   *  masterformat | uniformat | omniclass | uniclass | din276 | nrm | icms.
   *  Adapters set the codes they can derive (heuristics-driven for IFC); the
   *  UI can override per element. */
  classification?: Record<string, string>;
  /** Level of Development. "100" | "200" | "300" | "350" | "400" | "500".
   *  IFC adapters extract from Pset_VerificationStatus / Pset_LOD when present. */
  lod?: string;
  /** Provenance of the LOD value: "pset" (auto from model) | "manual" (UI). */
  lodSource?: "pset" | "manual" | "";
  properties?: Record<string, unknown>;
}

export interface CanonicalModelQuantity {
  id: string;
  elementId?: string | null;
  quantityType: string;
  value: number;
  unit: string;
  method: string;
  confidence?: number;
  metadata?: Record<string, unknown>;
}

export interface EstimateLensGroup {
  id: string;
  groupKey: string;
  label: string;
  elementClass: string;
  elementType?: string;
  system?: string;
  level?: string;
  material?: string;
  elementIds: string[];
  quantityIds: string[];
  quantities: Array<{
    quantityType: string;
    value: number;
    unit: string;
    confidence: number;
  }>;
  confidence: number;
  source: "native-schedule" | "native-quantity" | "geometry-derived" | "entity-index" | "adapter-fallback";
  metadata?: Record<string, unknown>;
}

export interface CanonicalModelIngestManifest {
  schemaVersion: 1;
  runStatus: ModelIngestRunStatus;
  adapter: ModelIngestCapability;
  provenance: ModelIngestSourceProvenance;
  units: string;
  summary: Record<string, unknown>;
  elementStats: Record<string, unknown>;
  artifacts: ModelIngestArtifact[];
  geometryArtifacts: ModelGeometryArtifact[];
  estimateLens: EstimateLensGroup[];
  issues: Array<{
    severity: "info" | "warning" | "error";
    code: string;
    message: string;
    elementId?: string | null;
    metadata?: Record<string, unknown>;
  }>;
}
