/**
 * Oracle Canvas — Canonical TypeScript Contracts
 * Mirrors the JSON Schema from Section 6.2 of the Oracle Architecture Document v1.0
 * These types replace the temporary OracleQueryResult contract.
 */

// ── Enums ─────────────────────────────────────────────────────────────────────

export type OracleRole =
  | 'junior_broker'
  | 'senior_broker'
  | 'sales_director'
  | 'marketing_operator'
  | 'data_steward'
  | 'compliance_reviewer'
  | 'platform_admin';

export type ComponentType =
  | 'textCanvas'
  | 'kpiTile'
  | 'barChart'
  | 'lineChart'
  | 'scatterPlot'
  | 'geoMap'
  | 'table'
  | 'pipelineBoard'
  | 'timeline'
  | 'heatmap'
  | 'forecastChart'
  | 'activityStream'
  | 'customMLVisualization'
  | 'errorNotice';

export type ComponentLifecycleState = 'draft' | 'active' | 'superseded' | 'archived' | 'revoked';

export type PrivacyTier = 'standard' | 'restricted' | 'sensitive';

export type SourceType = 'postgres' | 'warehouse' | 'api' | 'materialized_view' | 'derived_dataset' | 'inline';

export type CachePolicyMode = 'none' | 'ttl' | 'revision_scoped';

export type IntentClass = 'analytical' | 'operational' | 'mixed';

export type ExecutionStatus =
  | 'received'
  | 'planning'
  | 'validated'
  | 'executing'
  | 'completed'
  | 'failed'
  | 'clarification_required';

export type PageType = 'main' | 'fork';

export type ForkStatus = 'active' | 'merged' | 'closed';

export type MergeRequestStatus = 'open' | 'changes_requested' | 'approved' | 'merged' | 'closed';

export type TemplateStatus = 'catalog_active' | 'tenant_draft' | 'tenant_active' | 'archived' | 'revoked';

export type TemplateOrigin = 'premade' | 'synthesized' | 'cloned';

export type ShareMode = 'private' | 'direct_fork_only';

export type WidthMode = 'full' | 'half' | 'third';

export type VisibilityScope = 'private' | 'shared_fork' | 'tenant_team';

export type ComponentOriginType = 'catalog' | 'prompt_generated' | 'cloned' | 'merged' | 'edited';

export type PlacementMode =
  | 'append_after_last_visible_component'
  | 'insert_after_component'
  | 'replace_component'
  | 'group_under_section';

export type ActorType = 'user' | 'service' | 'ai';

export type LineageSourceKind =
  | 'table'
  | 'view'
  | 'materialization'
  | 'prompt'
  | 'component'
  | 'template'
  | 'merge_request';

export type ValidationStatus = 'validated' | 'rejected' | 'needs_review';

export type CommitKind = 'prompt' | 'merge' | 'rollback' | 'manual_edit';

// ── Sub-objects ───────────────────────────────────────────────────────────────

export interface CachePolicy {
  mode: CachePolicyMode;
  ttlSeconds?: number;
}

export interface DataSourceDescriptor {
  descriptorId: string;
  sourceType: SourceType;
  connectorId: string;
  dataset: string;
  authContextRef: string;
  queryTemplate: string;
  queryParameters: Record<string, unknown>;
  rowLimit: number;
  freshnessSlaSeconds?: number;
  cachePolicy?: CachePolicy;
  privacyTier: PrivacyTier;
  lineageRefs?: string[];
}

export interface DataBindings {
  dimensions: string[];
  measures: string[];
  series: string[];
  filters: Array<{
    field: string;
    operator: string;
    value: unknown;
  }>;
}

export interface ComponentProvenance {
  originType: ComponentOriginType;
  templateId?: string;
  promptExecutionId?: string;
  sourceComponentId?: string;
  sourceBranchId?: string;
  mergeRequestId?: string;
  createdBy: string;
  createdAt: string;
}

export interface RenderingHints {
  estimatedHeightPx: number;
  skeletonVariant: 'chart' | 'map' | 'table' | 'kpi' | 'pipeline' | 'timeline' | 'generic';
  virtualizationPriority: number;
}

export interface ComponentLayout {
  orderIndex: number;
  sectionId: string;
  widthMode: WidthMode;
  minHeightPx: number;
  stickyHeader: boolean;
}

export interface AccessControls {
  visibilityScope: VisibilityScope;
  allowedRoles: OracleRole[];
  redactionPolicy: string;
}

export interface StyleSignature {
  theme: string;
  paletteToken: string;
  motionProfile: string;
  density: 'compact' | 'comfortable';
  radiusScale: string;
  typographyScale: string;
}

export interface ValidationState {
  schema: 'pass' | 'fail';
  policy: 'pass' | 'fail';
  a11y: 'pass' | 'fail';
  performance: 'pass' | 'fail';
  status: ValidationStatus;
}

// ── Core Entities ─────────────────────────────────────────────────────────────

export interface CanvasComponent {
  componentId: string;
  type: ComponentType;
  title: string;
  description?: string;
  dataSourceDescriptor: DataSourceDescriptor;
  visualizationParameters: Record<string, unknown>;
  dataBindings: DataBindings;
  version: number;
  lifecycleState?: ComponentLifecycleState;
  provenance: ComponentProvenance;
  renderingHints: RenderingHints;
  layout: ComponentLayout;
  accessControls: AccessControls;
  styleSignature: StyleSignature;
  validationState: ValidationState;
  auditLog: string[];
  // Runtime-only: actual data rows fetched for this component
  dataRows?: Record<string, unknown>[];
}

export interface ForkRecord {
  forkId: string;
  sourcePageId: string;
  sourceBranchId: string;
  sourceRevision: number;
  forkPageId: string;
  forkBranchId: string;
  recipientUserId: string;
  createdBy: string;
  createdAt: string;
  status: ForkStatus;
}

export interface LineageRecord {
  lineageRecordId: string;
  tenantId: string;
  sourceKind: LineageSourceKind;
  sourceId: string;
  transformationType: string;
  transformationSpecHash?: string;
  producedKind: string;
  producedId: string;
  policySnapshotId?: string;
  createdAt: string;
}

export interface SharingPolicy {
  shareMode: ShareMode;
  allowReshare: boolean;
  defaultForkVisibility: 'private' | 'team';
}

export interface PagePresence {
  activeViewers: number;
  activeEditors: number;
  lastPresenceAt: string;
}

export interface PageAuditSummary {
  lastAuditEventId: string;
  eventCount: number;
}

export interface CanvasPage {
  pageId: string;
  tenantId: string;
  ownerId: string;
  branchId: string;
  branchName: string;
  pageType: PageType;
  title: string;
  createdAt: string;
  updatedAt: string;
  isShared: boolean;
  forks: ForkRecord[];
  mainBranchPointer: {
    pageId: string;
    branchId: string;
    revision: number;
  };
  baseRevision: number;
  headRevision: number;
  sharingPolicy: SharingPolicy;
  presence: PagePresence;
  lineage: LineageRecord[];
  audit: PageAuditSummary;
  components: CanvasComponent[];
}

export interface PromptExecution {
  executionId: string;
  tenantId: string;
  pageId: string;
  branchId: string;
  actorId: string;
  prompt: string;
  intentClass: IntentClass;
  status: ExecutionStatus;
  modelRuntime: string;
  semanticModelVersion: string;
  retrievalPlan?: Record<string, unknown>;
  visualizationPlan?: Record<string, unknown>;
  warnings: string[];
  summary?: string;
  componentsCreated?: string[];
  createdAt: string;
  completedAt?: string;
}

export interface ComponentTemplate {
  templateId: string;
  tenantId: string;
  name: string;
  category: string;
  status: TemplateStatus;
  origin: TemplateOrigin;
  version: string;
  acceptedShapes: string[];
  styleSignature?: StyleSignature;
  validationState?: ValidationState;
  provenance?: ComponentProvenance;
  createdAt: string;
  updatedAt: string;
}

export interface ConflictRecord {
  conflictId: string;
  conflictClass:
    | 'component_content_conflict'
    | 'query_descriptor_conflict'
    | 'layout_slot_conflict'
    | 'access_policy_conflict'
    | 'delete_edit_conflict'
    | 'safe_append'
    | 'safe_reorder';
  componentId: string;
  field?: string;
  sourceValue?: unknown;
  targetValue?: unknown;
  description: string;
}

export interface DiffSummary {
  componentsAdded: number;
  componentsEdited: number;
  componentsReordered: number;
  componentsDeleted: number;
}

export interface MergeRequest {
  mergeRequestId: string;
  tenantId: string;
  sourcePageId: string;
  sourceBranchId: string;
  sourceHeadRevision: number;
  targetPageId: string;
  targetBranchId: string;
  targetBaseRevision: number;
  title: string;
  description?: string;
  status: MergeRequestStatus;
  conflicts: ConflictRecord[];
  diffSummary?: DiffSummary;
  createdBy: string;
  reviewedBy?: string;
  createdAt: string;
  updatedAt: string;
}

export interface AuditEvent {
  auditEventId: string;
  tenantId: string;
  entityType: string;
  entityId: string;
  action: string;
  actorId: string;
  actorType: ActorType;
  correlationId: string;
  executionId?: string;
  createdAt: string;
  details: Record<string, unknown>;
}

export interface UserProfile {
  userId: string;
  tenantId: string;
  email: string;
  displayName: string;
  role: OracleRole;
  timezone: string;
  locale: string;
  defaultPageId: string;
  canvasPreferences: {
    defaultDensity: 'compact' | 'comfortable';
    defaultPlacementMode: PlacementMode;
    showLineageBadges: boolean;
  };
  policyProfileId: string;
  createdAt: string;
  updatedAt: string;
}

// ── API Request/Response contracts ────────────────────────────────────────────

export interface PromptSubmitRequest {
  clientRequestId: string;
  branchId: string;
  prompt: string;
  conversationContext?: Array<{ role: 'user' | 'assistant'; content: string }>;
  placementMode?: PlacementMode;
}

export interface PromptSubmitResponse {
  executionId: string;
  status: ExecutionStatus;
  pageId: string;
  branchId: string;
  headRevision: number;
  componentsCreated: string[];
  components: CanvasComponent[];
  summary: string;
  warnings: string[];
}

export interface CanvasPageRevision {
  revisionId: string;
  pageId: string;
  tenantId: string;
  revisionNumber: number;
  commitKind: CommitKind;
  commitSummary?: string;
  actorId: string;
  executionId?: string;
  mergeRequestId?: string;
  createdAt: string;
}

export interface ForkCreateRequest {
  recipientUserId: string;
  sourceRevision: number;
  visibility: 'private' | 'team';
  message?: string;
}

export interface ForkCreateResponse {
  forkId: string;
  forkPageId: string;
  forkBranchId: string;
  status: ForkStatus;
  sourceRevision: number;
}

export interface MergeRequestCreateRequest {
  sourcePageId: string;
  sourceBranchId: string;
  targetPageId: string;
  targetBranchId: string;
  title: string;
  description?: string;
}

export interface MergeReviewRequest {
  decision: 'approve' | 'reject' | 'changes_requested';
  comment?: string;
  resolutions?: Array<{
    conflictId: string;
    resolutionType: 'source_wins' | 'target_wins' | 'manual_composite';
    resolvedPayloadHash?: string;
    comment?: string;
  }>;
}

// ── WebSocket event types ─────────────────────────────────────────────────────

export type OracleWSEventType =
  | 'oracle.prompt.received'
  | 'oracle.prompt.validated'
  | 'oracle.prompt.failed'
  | 'oracle.page.revision.committed'
  | 'oracle.page.rollback.committed'
  | 'oracle.fork.created'
  | 'oracle.merge_request.opened'
  | 'oracle.merge_request.updated'
  | 'oracle.merge_request.merged'
  | 'oracle.component.template.promoted'
  | 'oracle.presence.updated';

export interface OracleWSMessage {
  type: OracleWSEventType;
  tenantId: string;
  pageId?: string;
  branchId?: string;
  correlationId: string;
  timestamp: string;
  payload: Record<string, unknown>;
}

// ── API Error envelope ────────────────────────────────────────────────────────

export interface OracleAPIError {
  error: {
    code: string;
    message: string;
    retryable: boolean;
    correlationId: string;
    details?: Record<string, unknown>;
  };
}

export interface OracleEnvelope<T> {
  status: 'ok';
  data: T;
  meta?: Record<string, unknown>;
}
