export type UUID = string;

export type PropositionState =
  | "unseen"
  | "hinted"
  | "confirmed"
  | "conflicted"
  | "rejected";

export type EvidenceSource =
  | "registry"
  | "lexical"
  | "lemma"
  | "fuzzy"
  | "dense"
  | "llm"
  | "coref"
  | "numeric"
  | "negation";

export type ConceptKind =
  | "entity"
  | "role"
  | "proceeding"
  | "forum"
  | "legal_claim"
  | "action"
  | "state"
  | "outcome"
  | "amount"
  | "date"
  | "relation"
  | "polarity";

export interface AliasSpec {
  text: string;
  weight?: number;                 // default 1.0
  strength?: "strong" | "medium" | "weak";
  allowFuzzy?: boolean;            // default false
  allowLemma?: boolean;            // default true
  clientSafe?: boolean;            // may be shipped to client hint runtime
}

export interface ConceptSpec {
  id: string;
  kind: ConceptKind;
  canonical: string;
  aliases: AliasSpec[];
  negatives?: AliasSpec[];
  incompatibleConceptIds?: string[];
  notes?: string;
}

export interface EntitySpec {
  id: string;
  type: "person" | "organization" | "court" | "proceeding" | "amount" | "date" | "statute" | "other";
  display: string;
  aliases: string[];
  roles?: string[];
  attributes?: Record<string, string | number | boolean>;
}

export interface FactAtom {
  id: string;
  subjectId: string;
  predicate: string;
  objectId?: string;
  objectLiteral?: string | number | boolean;
}

export interface SlotSpec {
  id: string;
  name: string;
  kind: ConceptKind;
  conceptIds?: string[];
  entityIds?: string[];
  roleNames?: string[];
  requiresAllConceptIds?: boolean; // default false; otherwise any concept may satisfy
  minConfidence: number;           // [0,1]
  weight?: number;                 // default 1.0
  disallowAliases?: string[];
  notes?: string;
}

export interface PropositionSpec {
  id: string;
  elementId: string;
  circleLabel: string;
  canonical: string;
  kind: "fact" | "inference" | "conclusion";
  requiredSlots: SlotSpec[];
  optionalSlots?: SlotSpec[];
  positives: string[];
  paraphrasePositives: string[];
  nearMisses: string[];
  fillerNegatives: string[];
  contradictions?: string[];
  whyMatters: string;
}

export interface ElementSpec {
  id: string;
  label: string;
  propositionIds: string[];
  completionRule:
    | { mode: "all_of" }
    | { mode: "k_of_n"; k: number };
}

export interface DrillAuthoringV2 {
  version: "2.0";
  drillId: string;
  doctrineId: string;
  title: string;
  ruleText: string;
  factPattern: string;
  entityRegistry: EntitySpec[];
  factTable: FactAtom[];
  elements: ElementSpec[];
  propositions: PropositionSpec[];
  conceptLibraryRefs: string[];
  pedagogy?: {
    ruleExplanation?: string;
    formulaScaffold?: string;
    commonMistakes?: string[];
  };
}

export interface CompiledAlias {
  conceptId: string;
  aliasText: string;
  normalized: string;
  tokenCount: number;
  weight: number;
  source: "alias" | "negative";
  clientSafe: boolean;
}

export interface SlotRuntime {
  id: string;
  kind: ConceptKind;
  minConfidence: number;
  weight: number;
  conceptIds: string[];
  entityIds: string[];
  roleNames: string[];
  disallowAliases: string[];
}

export interface PropositionRuntime {
  id: string;
  elementId: string;
  circleLabel: string;
  canonical: string;
  kind: "fact" | "inference" | "conclusion";
  requiredSlots: SlotRuntime[];
  optionalSlots: SlotRuntime[];
  discriminatorAliasTexts: string[];
  densePrototypeTexts: string[];
  negativePrototypeTexts: string[];
  llmEnabled: boolean;
}

export interface CompiledDrillV2 {
  version: "2.0-compiled";
  drillId: string;
  buildHash: string;
  analysisPolicy: {
    liveDebounceMs: number;
    idleLlmDebounceMs: number;
    downgradeHoldMs: number;
    lexicalCandidateMinDistinctSlots: number;
    denseCandidateMinSimilarity: number;
    llmMaxCallsPerSession: number;
  };
  entityRegistry: EntitySpec[];
  compiledAliases: CompiledAlias[];
  propositions: PropositionRuntime[];
  clientRuntime: {
    propositionHints: Array<{
      propositionId: string;
      aliasTexts: string[];
    }>;
  };
}

export interface EvidenceSpan {
  start: number;
  end: number;
  text: string;
}

export interface SlotEvidence {
  slotId: string;
  source: EvidenceSource;
  confidence: number;
  span: EvidenceSpan;
  conceptId?: string;
  entityId?: string;
  notes?: string;
}

export interface SlotDecision {
  slotId: string;
  satisfied: boolean;
  confidence: number;
  evidence: SlotEvidence[];
  conflicts?: SlotEvidence[];
}

export interface PropositionDecision {
  propositionId: string;
  state: PropositionState;
  coverage: number;  // weighted satisfied required-slot share
  rationale: string;
  slotDecisions: SlotDecision[];
  updatedAtRevision: number;
}

export interface AnalyzeRequest {
  sessionId: string;
  revision: number;
  mode: "live" | "idle" | "submit";
  responseText: string;
  changedRanges: Array<{ start: number; end: number }>;
}

export interface AnalyzeResponse {
  sessionId: string;
  revision: number;
  propositions: PropositionDecision[];
  elements: Array<{
    elementId: string;
    state: "incomplete" | "complete";
    completionRatio: number;
  }>;
  llmTriggered: boolean;
  serverLatencyMs: number;
}
