import { randomUUID } from "crypto";

// ---------------------------------------------------------------------------
// JSON value type (replaces Prisma.JsonValue for the SDK)
// ---------------------------------------------------------------------------

export type JsonValue =
  | string
  | number
  | boolean
  | null
  | JsonValue[]
  | { [key: string]: JsonValue };

// ---------------------------------------------------------------------------
// Enums (as const + type union pattern — NO TypeScript enum keyword)
// ---------------------------------------------------------------------------

export const TraceStatus = {
  RUNNING: "RUNNING",
  COMPLETED: "COMPLETED",
  ERROR: "ERROR",
} as const;
export type TraceStatus = (typeof TraceStatus)[keyof typeof TraceStatus];

export const DecisionType = {
  TOOL_SELECTION: "TOOL_SELECTION",
  ROUTING: "ROUTING",
  RETRY: "RETRY",
  ESCALATION: "ESCALATION",
  MEMORY_RETRIEVAL: "MEMORY_RETRIEVAL",
  PLANNING: "PLANNING",
  CUSTOM: "CUSTOM",
} as const;
export type DecisionType = (typeof DecisionType)[keyof typeof DecisionType];

export const SpanType = {
  LLM_CALL: "LLM_CALL",
  TOOL_CALL: "TOOL_CALL",
  MEMORY_OP: "MEMORY_OP",
  CHAIN: "CHAIN",
  AGENT: "AGENT",
  CUSTOM: "CUSTOM",
} as const;
export type SpanType = (typeof SpanType)[keyof typeof SpanType];

export const SpanStatus = {
  RUNNING: "RUNNING",
  COMPLETED: "COMPLETED",
  ERROR: "ERROR",
} as const;
export type SpanStatus = (typeof SpanStatus)[keyof typeof SpanStatus];

export const EventType = {
  ERROR: "ERROR",
  RETRY: "RETRY",
  FALLBACK: "FALLBACK",
  CONTEXT_OVERFLOW: "CONTEXT_OVERFLOW",
  USER_FEEDBACK: "USER_FEEDBACK",
  CUSTOM: "CUSTOM",
} as const;
export type EventType = (typeof EventType)[keyof typeof EventType];

// ---------------------------------------------------------------------------
// Wire-format interfaces (camelCase, matching POST /api/traces contract)
// ---------------------------------------------------------------------------

export interface DecisionPointPayload {
  id: string;
  type: DecisionType;
  chosen: JsonValue;
  alternatives: JsonValue[];
  reasoning?: string;
  contextSnapshot?: JsonValue;
  durationMs?: number;
  costUsd?: number;
  parentSpanId?: string;
  timestamp: string;
}

export interface SpanPayload {
  id: string;
  parentSpanId?: string;
  name: string;
  type: SpanType;
  input?: JsonValue;
  output?: JsonValue;
  tokenCount?: number;
  costUsd?: number;
  durationMs?: number;
  status: SpanStatus;
  statusMessage?: string;
  startedAt: string;
  endedAt?: string;
  metadata?: JsonValue;
}

export interface EventPayload {
  id: string;
  spanId?: string;
  type: EventType;
  name: string;
  metadata?: JsonValue;
  timestamp: string;
}

export interface TracePayload {
  id: string;
  name: string;
  sessionId?: string;
  status: TraceStatus;
  tags: string[];
  metadata?: JsonValue;
  totalCost?: number;
  totalTokens?: number;
  totalDuration?: number;
  startedAt: string;
  endedAt?: string;
  decisionPoints: DecisionPointPayload[];
  spans: SpanPayload[];
  events: EventPayload[];
}

// ---------------------------------------------------------------------------
// Helper functions
// ---------------------------------------------------------------------------

/** Generate a v4 UUID. */
export function generateId(): string {
  return randomUUID();
}

/** Return the current time as an ISO-8601 string. */
export function nowISO(): string {
  return new Date().toISOString();
}
