export type WorkspaceScope = 'single_company';

export type ResearchStage =
  | 'capture'
  | 'organize'
  | 'thesis'
  | 'drafting'
  | 'monitor';

export type WorkspaceViewKind =
  | 'canvas'
  | 'kanban'
  | 'graph'
  | 'thesis_builder'
  | 'memo_drafting'
  | 'evidence_trace'
  | 'catalyst_risk_map'
  | 'timeline'
  | 'model';

export type NoteType =
  | 'fact'
  | 'quote'
  | 'management_signal'
  | 'claim'
  | 'thesis'
  | 'sub_thesis'
  | 'risk'
  | 'catalyst'
  | 'valuation_point'
  | 'scenario_assumption'
  | 'industry_observation'
  | 'competitor_comparison'
  | 'question'
  | 'contradiction'
  | 'uncertainty'
  | 'follow_up_task'
  | 'source_reference'
  | 'event_takeaway'
  | 'channel_check'
  | 'mosaic_insight';

export type AnalystStatus =
  | 'captured'
  | 'review_queue'
  | 'reviewed'
  | 'accepted'
  | 'needs_follow_up'
  | 'dismissed';

export type EvidenceStatus =
  | 'unsourced'
  | 'source_linked'
  | 'quoted'
  | 'corroborated'
  | 'inferred'
  | 'contradicted'
  | 'stale'
  | 'superseded';

export type GhostStatus =
  | 'none'
  | 'candidate_input'
  | 'ghost_generated'
  | 'ghost_promoted'
  | 'ghost_dismissed';

export type ThesisStatus =
  | 'none'
  | 'candidate_support'
  | 'candidate_core'
  | 'accepted_support'
  | 'accepted_core'
  | 'bull_case'
  | 'bear_case';

export type TimeHorizon =
  | 'near_term'
  | 'next_earnings'
  | 'twelve_month'
  | 'multi_year';

export type ScenarioKind =
  | 'base'
  | 'bull'
  | 'bear'
  | 'downside_case'
  | 'upside_case';

export type NotePriority = 'low' | 'normal' | 'high' | 'critical';

export type StaleReason =
  | 'new_filing'
  | 'new_guidance'
  | 'new_earnings'
  | 'source_expired'
  | 'note_updated'
  | 'superseded_by_analyst';

export type SourceKind =
  | 'filing'
  | 'transcript'
  | 'article'
  | 'news_feed'
  | 'model'
  | 'manual';

export type FreshnessBucket = 'fresh' | 'aging' | 'stale';

export type ProvenanceActor =
  | 'manual'
  | 'ai_enrichment'
  | 'ghost_conversion'
  | 'import';

export type CaptureMethod =
  | 'quick_entry'
  | 'transcript_clip'
  | 'filing_extract'
  | 'news_import'
  | 'manual_link';

export type LinkType =
  | 'supports'
  | 'contradicts'
  | 'qualifies'
  | 'derived_from'
  | 'sourced_by'
  | 'updates'
  | 'supersedes'
  | 'peer_readthrough'
  | 'valuation_depends_on'
  | 'catalyst_for'
  | 'risk_to'
  | 'timeframe_conflict'
  | 'assumption_for'
  | 'management_vs_reality';

export type LinkStrength = 'weak' | 'medium' | 'strong' | 'critical';

export type EvidenceBasis =
  | 'lexical'
  | 'shared_source'
  | 'temporal'
  | 'numerical'
  | 'structured'
  | 'model_assisted';

export type LinkOrigin = 'heuristic' | 'ai' | 'analyst';

export type GhostNoteClass =
  | 'candidate_thesis'
  | 'candidate_risk'
  | 'candidate_catalyst'
  | 'missing_evidence_prompt'
  | 'contradiction_alert'
  | 'valuation_bridge'
  | 'scenario_implication'
  | 'memo_outline_suggestion'
  | 'claim_support_gap'
  | 'claim_pressure_test'
  | 'thesis_dependency_gap'
  | 'contradiction_resolution'
  | 'evidence_quality_warning'
  | 'stale_support_warning'
  | 'numerical_claim_verification'
  | 'thesis_synthesis_candidate'
  | 'model_assumption_challenge'
  | 'valuation_sensitivity_alert';

export type GhostTone = 'tentative';

export type GhostVisibilityState = 'hidden' | 'collapsed' | 'visible' | 'pinned';

export type GhostLifecycleState =
  | 'generated'
  | 'visible'
  | 'ignored'
  | 'dismissed'
  | 'accepted'
  | 'converted'
  | 'superseded'
  | 'stale';

export type GhostResolutionStatus =
  | 'open'
  | 'in_progress'
  | 'strengthened'
  | 'weakened'
  | 'waived'
  | 'blocked';

export type GhostTargetClaimKind =
  | 'core_thesis'
  | 'sub_claim'
  | 'supporting_point'
  | 'risk'
  | 'catalyst'
  | 'assumption';

export type GhostRecommendedAction =
  | 'find_primary_source'
  | 'link_existing_note'
  | 'rewrite_claim'
  | 'downgrade_to_inference'
  | 'mark_waived'
  | 'resolve_contradiction';

export type GhostSupportStrength = 'none' | 'weak' | 'mixed' | 'strong';

export type GhostFreshnessRisk = 'low' | 'medium' | 'high';

export type MemoSectionKind =
  | 'stock_pitch'
  | 'investment_memo'
  | 'bull_case'
  | 'bear_case'
  | 'catalyst_calendar'
  | 'risk_register'
  | 'valuation_write_up'
  | 'earnings_preview'
  | 'earnings_recap'
  | 'watchlist_update';

export type JobKind =
  | 'enrich_note'
  | 'infer_links'
  | 'evaluate_duplicates'
  | 'evaluate_ghosts'
  | 'refresh_source_metadata'
  | 'recalculate_staleness';

export type JobStatus = 'queued' | 'running' | 'completed' | 'failed' | 'skipped';

export type AuditEntityKind =
  | 'workspace'
  | 'note'
  | 'link'
  | 'ghost'
  | 'source'
  | 'job'
  | 'memo_export';

export type AuditActor = 'analyst' | 'system' | 'ai';

export type GhostReviewAction = 'accept' | 'ignore' | 'dismiss' | 'pin';

export type ResearchDensityMode = 'compact' | 'comfortable' | 'detailed';

export type ResearchFilePreviewKind = 'image' | 'pdf' | 'text' | 'none';

export type ModelTemplateType =
  | 'blank'
  | 'dcf'
  | 'three_statement'
  | 'comparable_companies'
  | 'scenario'
  | 'historical_trend';

export type ModelEvidenceStatus =
  | 'unsourced'
  | 'single_source'
  | 'corroborated'
  | 'inferred'
  | 'contradicted'
  | 'stale';

export interface ModelInfo {
  taskProfile: string;
  model: string;
  provider?: string;
}

export interface NoteProvenance {
  createdBy: ProvenanceActor;
  captureMethod: CaptureMethod;
  sourceKind: SourceKind;
  originNoteId?: string;
  originGhostId?: string;
  modelInfo?: ModelInfo;
  createdAt: string;
  rawInputHash: string;
}

export interface SourceExcerpt {
  sourceId: string;
  excerptText?: string;
  locationLabel?: string;
  startOffset?: number;
  endOffset?: number;
}

export interface NoteEmbed {
  id: string;
  sourceId?: string;
  url: string;
  canonicalUrl?: string;
  title: string;
  publisher?: string;
  excerpt?: string;
  kind: SourceKind;
  imageUrl?: string;
}

export interface NoteEmbedInput {
  url: string;
  canonicalUrl?: string;
  title: string;
  publisher?: string;
  excerpt?: string;
  kind: SourceKind;
  imageUrl?: string;
}

export interface ValuationRef {
  metric: string;
  multiple?: number;
  unit?: string;
  basis?: string;
}

export interface ResearchWorkspace {
  id: string;
  name: string;
  primaryTicker: string;
  scope: WorkspaceScope;
  stage: ResearchStage;
  defaultView: WorkspaceViewKind;
  pinnedNoteIds: string[];
  archived: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface ResearchNote {
  id: string;
  workspaceId: string;
  companyId?: string;
  ticker?: string;
  sourceId?: string;
  rawText: string;
  cleanedText: string;
  bodyHtml?: string;
  embeds: NoteEmbed[];
  fileIds: string[];
  title?: string;
  noteType: NoteType;
  subtype?: string;
  analystStatus: AnalystStatus;
  aiAnnotation?: string;
  confidence: number;
  evidenceStatus: EvidenceStatus;
  inferredLinks: string[];
  ghostStatus: GhostStatus;
  thesisStatus: ThesisStatus;
  createdAt: string;
  updatedAt: string;
  provenance: NoteProvenance;
  tags: string[];
  catalysts: string[];
  risks: string[];
  valuationRefs: ValuationRef[];
  timeHorizon?: TimeHorizon;
  scenario?: ScenarioKind;
  priority: NotePriority;
  pinned: boolean;
  archived: boolean;
  revision: number;
  sourceExcerpt?: SourceExcerpt;
  lastEnrichedAt?: string;
  lastLinkedAt?: string;
  staleReason?: StaleReason;
  supersededByNoteId?: string;
}

export interface NoteLink {
  id: string;
  workspaceId: string;
  fromNoteId: string;
  toNoteId: string;
  linkType: LinkType;
  directional: boolean;
  confidence: number;
  strength: LinkStrength;
  evidenceBasis: EvidenceBasis;
  createdBy: LinkOrigin;
  createdAt: string;
  updatedAt: string;
  sourceRevisionPair: [number, number];
  stale: boolean;
  staleReason?: string;
}

export interface GhostNote {
  id: string;
  workspaceId: string;
  ghostClass: GhostNoteClass;
  headline: string;
  body: string;
  tone: GhostTone;
  confidence: number;
  visibilityState: GhostVisibilityState;
  state: GhostLifecycleState;
  supportingNoteIds: string[];
  contradictingNoteIds: string[];
  sourceIds: string[];
  evidenceThresholdMet: boolean;
  createdAt: string;
  updatedAt: string;
  supersededByGhostId?: string;
  promotedNoteId?: string;
  memoSectionHint?: MemoSectionKind;
  targetNoteId?: string;
  parentThesisNoteId?: string;
  targetClaimText?: string;
  targetClaimKind?: GhostTargetClaimKind;
  whyItMatters?: string;
  currentSupportSummary?: string;
  counterCase?: string;
  recommendedAction?: GhostRecommendedAction;
  recommendedActionRationale?: string;
  resolutionStatus?: GhostResolutionStatus;
  leverageScore?: number;
  supportStrength?: GhostSupportStrength;
  freshnessRisk?: GhostFreshnessRisk;
  agentReasoningVersion?: number;
}

export interface SourceRecord {
  id: string;
  workspaceId: string;
  kind: SourceKind;
  ticker?: string;
  title: string;
  publisher?: string;
  url?: string;
  canonicalUrl?: string;
  filingAccession?: string;
  formType?: string;
  publishedAt?: string;
  asOfDate?: string;
  ingestedAt: string;
  freshnessBucket: FreshnessBucket;
  checksum?: string;
  metadataJson: Record<string, unknown>;
  supersededBySourceId?: string;
}

export interface ResearchFile {
  id: string;
  workspaceId: string;
  originalName: string;
  storedPath: string;
  mimeType?: string;
  sizeBytes: number;
  checksum: string;
  previewKind: ResearchFilePreviewKind;
  extractedText?: string;
  extractedTextSource?: 'liteparse';
  extractedTextTruncated?: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface ModelWorkbookCell {
  value?: string | number | boolean | null;
  formula?: string;
  format?: 'number' | 'percent' | 'currency';
  cellId?: string;
  binding?: {
    kind: 'sec_edgar' | 'mapping' | 'market';
    field: string;
  };
}

export interface ModelWorkbookSheet {
  id: string;
  name: string;
  cells: Record<string, ModelWorkbookCell>;
}

export interface ModelWorkbook {
  version: number;
  sheets: ModelWorkbookSheet[];
  activeSheetId?: string;
  metadata?: {
    mosaiciq?: Record<string, unknown>;
    univerSnapshot?: Record<string, unknown>;
  };
}

export interface ModelCellAnnotation {
  cellId: string;
  sheetId: string;
  address: string;
  linkedNoteIds: string[];
  evidenceStatus: ModelEvidenceStatus;
  confidenceScore: number;
  lastEvidenceUpdate?: string;
  updatedAt: string;
}

export interface FinancialModel {
  id: string;
  workspaceId: string;
  name: string;
  ticker?: string;
  templateType: ModelTemplateType;
  scenarioGroupId?: string;
  workbookJson: ModelWorkbook;
  annotations: ModelCellAnnotation[];
  createdAt: string;
  updatedAt: string;
}

export interface ModelDataBinding {
  id: string;
  modelId: string;
  sheetId: string;
  range: string;
  kind: 'sec_edgar' | 'mapping' | 'market';
  sourceKey: string;
  refreshPolicy: 'manual' | 'on_open' | 'on_source_update';
  lastRefreshAt?: string;
  createdAt: string;
  updatedAt: string;
}

export interface EvaluatedModelCell {
  sheetId: string;
  address: string;
  value: string | number | boolean | null;
}

export interface ModelFormulaError {
  sheetId: string;
  address: string;
  formula: string;
  message: string;
}

export interface ModelDependencyEdge {
  fromSheetId: string;
  fromAddress: string;
  toSheetId: string;
  toAddress: string;
}

export interface EvaluateFinancialModelResult {
  evaluatedCells: EvaluatedModelCell[];
  formulaErrors: ModelFormulaError[];
  dependencyGraph: ModelDependencyEdge[];
}

export interface ExportFinancialModelXlsxResult {
  filePath: string;
  modelId: string;
  sheetCount: number;
  exportedAt: string;
}

export interface PipelineJob {
  id: string;
  workspaceId: string;
  entityId: string;
  jobKind: JobKind;
  status: JobStatus;
  attemptCount: number;
  maxAttempts: number;
  nextAttemptAt?: string;
  lastError?: string;
  payloadJson: Record<string, unknown>;
  createdAt: string;
  updatedAt: string;
}

export interface AuditEvent {
  id: string;
  workspaceId: string;
  entityId: string;
  entityKind: AuditEntityKind;
  action: string;
  actor: AuditActor;
  priorRevision?: number;
  newRevision?: number;
  jobId?: string;
  sourceIds: string[];
  detail?: string;
  createdAt: string;
}

export interface PlacementHint {
  tileLane: string;
  kanbanColumn: string;
  graphAnchorNoteId?: string;
}

export interface NoteCaptureResult {
  note: ResearchNote;
  placementHint: PlacementHint;
  queuedJobs: PipelineJob[];
}

export interface GraphNode {
  id: string;
  label: string;
  kind: string;
  confidence: number;
  evidenceStatus: EvidenceStatus;
}

export interface GraphEdge {
  id: string;
  from: string;
  to: string;
  linkType: LinkType;
  strength: LinkStrength;
  confidence: number;
}

export interface KanbanColumn {
  key: string;
  label: string;
  notes: ResearchNote[];
}

export interface TimelineEvent {
  id: string;
  label: string;
  noteId: string;
  at?: string;
}

export interface MemoBlockCandidate {
  sectionKind: MemoSectionKind;
  headline: string;
  body: string;
  sourceNoteIds: string[];
  citationRefs: string[];
  confidence: number;
  accepted: boolean;
}

export interface WorkspaceProjection {
  workspace: ResearchWorkspace;
  activeView: WorkspaceViewKind;
  notes: ResearchNote[];
  links: NoteLink[];
  ghosts: GhostNote[];
  memoBlocks: MemoBlockCandidate[];
  graphNodes: GraphNode[];
  graphEdges: GraphEdge[];
  kanbanColumns: KanbanColumn[];
  timelineEvents: TimelineEvent[];
}

export interface ResearchBundleExport {
  workspace: ResearchWorkspace;
  notes: ResearchNote[];
  links: NoteLink[];
  ghosts: GhostNote[];
  sources: SourceRecord[];
  auditEvents: AuditEvent[];
  markdownMemo: string;
  jsonBundle: Record<string, unknown>;
}

export interface NoteAuditTrail {
  note: ResearchNote;
  links: NoteLink[];
  relatedGhosts: GhostNote[];
  sources: SourceRecord[];
  files: ResearchFile[];
  auditEvents: AuditEvent[];
  memoBlocks: MemoBlockCandidate[];
}

export interface SourceReferenceInput {
  kind: SourceKind;
  title?: string;
  url?: string;
  publishedAt?: string;
  filingAccession?: string;
  formType?: string;
  excerptText?: string;
  locationLabel?: string;
}

export interface PreviewLinkRequest {
  url: string;
  kind?: SourceKind;
}

export interface PreviewLinkResult {
  embed: NoteEmbedInput;
  sourceRef: SourceReferenceInput;
  suggestedTitle?: string;
  suggestedBodyText?: string;
}

export interface CreateResearchWorkspaceRequest {
  name: string;
  primaryTicker: string;
  stage?: ResearchStage;
  defaultView?: WorkspaceViewKind;
}

export interface CaptureResearchNoteRequest {
  workspaceId: string;
  rawText: string;
  bodyHtml?: string;
  embeds?: NoteEmbedInput[];
  fileIds?: string[];
  companyId?: string;
  ticker?: string;
  sourceRef?: SourceReferenceInput;
  positionHint?: string;
  userNoteTypeOverride?: NoteType;
}

export interface UpdateResearchNoteRequest {
  noteId: string;
  rawText?: string;
  bodyHtml?: string;
  embeds?: NoteEmbedInput[];
  fileIds?: string[];
  title?: string;
  noteType?: NoteType;
  subtype?: string;
  analystStatus?: AnalystStatus;
  pinned?: boolean;
  priority?: NotePriority;
  thesisStatus?: ThesisStatus;
}

export interface ArchiveResearchNoteRequest {
  noteId: string;
  archived: boolean;
}

export interface ListResearchNotesRequest {
  workspaceId: string;
  includeArchived?: boolean;
  noteType?: NoteType;
}

export interface GetNotesByTickerRequest {
  ticker: string;
  limit?: number;
}

export interface GetWorkspaceProjectionRequest {
  workspaceId: string;
  view?: WorkspaceViewKind;
}

export interface ListFinancialModelsRequest {
  workspaceId: string;
}

export interface GetFinancialModelRequest {
  modelId: string;
}

export interface CreateFinancialModelRequest {
  workspaceId: string;
  name: string;
  ticker?: string;
  templateType?: ModelTemplateType;
}

export interface SaveFinancialModelRequest {
  modelId: string;
  workbookJson: ModelWorkbook;
  annotations?: ModelCellAnnotation[];
}

export interface EvaluateFinancialModelRequest {
  modelId?: string;
  workbookJson?: ModelWorkbook;
}

export interface ListModelDataBindingsRequest {
  modelId: string;
}

export interface SaveModelDataBindingRequest {
  binding: ModelDataBinding;
}

export interface RefreshModelDataBindingsRequest {
  modelId: string;
  bindingIds?: string[];
}

export interface LinkNoteToModelCellRequest {
  modelId: string;
  sheetId: string;
  address: string;
  noteId: string;
}

export interface UnlinkNoteFromModelCellRequest {
  modelId: string;
  sheetId: string;
  address: string;
  noteId: string;
}

export interface UpdateModelCellAnnotationRequest {
  modelId: string;
  annotation: ModelCellAnnotation;
}

export interface ListModelCellAnnotationsRequest {
  modelId: string;
}

export interface ExportFinancialModelXlsxRequest {
  modelId: string;
}

export interface ListNoteLinksRequest {
  workspaceId: string;
  noteId?: string;
}

export interface ListWorkspaceGhostNotesRequest {
  workspaceId: string;
  includeHidden?: boolean;
}

export interface ReviewGhostNoteRequest {
  ghostNoteId: string;
  action: GhostReviewAction;
}

export interface ResolveGhostInterventionRequest {
  ghostNoteId: string;
  workspaceId: string;
  resolutionStatus: GhostResolutionStatus;
  actionTaken?: GhostRecommendedAction;
  notes?: string;
  linkedNoteIds?: string[];
}

export interface PromoteNoteToThesisRequest {
  noteId: string;
  thesisStatus?: ThesisStatus;
  noteType?: NoteType;
}

export interface RetryResearchJobsRequest {
  workspaceId: string;
  jobKind?: JobKind;
}

export interface ListResearchJobsRequest {
  workspaceId: string;
  jobKind?: JobKind;
}

export interface GetNoteAuditTrailRequest {
  noteId: string;
}

export interface UploadResearchFileInput {
  name: string;
  mimeType?: string;
  bytes: number[];
  extractedText?: string;
  extractedTextSource?: 'liteparse';
  extractedTextTruncated?: boolean;
}

export interface UploadResearchFilesRequest {
  workspaceId: string;
  files: UploadResearchFileInput[];
}

export interface ListResearchFilesRequest {
  workspaceId: string;
}

export interface GetResearchFileTextPreviewRequest {
  fileId: string;
  maxBytes?: number;
}

export interface ResearchFileTextPreview {
  fileId: string;
  text: string;
  truncated: boolean;
}

export interface ExportResearchBundleRequest {
  workspaceId: string;
}

export interface ResearchWorkspaceUpdateEvent {
  workspaceId: string;
  workspace: ResearchWorkspace;
}

export interface ResearchNoteUpdateEvent {
  workspaceId: string;
  note: ResearchNote;
}

export interface ResearchGhostUpdateEvent {
  workspaceId: string;
  ghost: GhostNote;
}

export interface ResearchJobUpdateEvent {
  workspaceId: string;
  job: PipelineJob;
}

export interface ResearchFilters {
  search: string;
  noteTypes: NoteType[];
  evidenceStatuses: EvidenceStatus[];
  showArchived: boolean;
  showGhosts: boolean;
}

export interface ResearchNavigationIntent {
  ticker?: string;
  workspaceId?: string;
  preferredView?: WorkspaceViewKind;
  seedNote?: string;
  terminalNoteSeed?: {
    rawText?: string;
    ticker?: string;
    contextLabel?: string;
  };
}

export const RESEARCH_VIEWS: Array<{
  key: WorkspaceViewKind;
  label: string;
  shortLabel: string;
}> = [
  { key: 'canvas', label: 'Canvas', shortLabel: 'Canvas' },
  { key: 'kanban', label: 'By Type', shortLabel: 'Kanban' },
  { key: 'graph', label: 'Graph', shortLabel: 'Graph' },
  { key: 'thesis_builder', label: 'Thesis', shortLabel: 'Thesis' },
  { key: 'memo_drafting', label: 'Memo', shortLabel: 'Memo' },
  { key: 'evidence_trace', label: 'Evidence', shortLabel: 'Evidence' },
  { key: 'catalyst_risk_map', label: 'Catalyst / Risk', shortLabel: 'Map' },
  { key: 'timeline', label: 'Timeline', shortLabel: 'Timeline' },
  { key: 'model', label: 'Model', shortLabel: 'Model' },
];

export const DENSITY_MODES: ResearchDensityMode[] = [
  'compact',
  'comfortable',
  'detailed',
];

export interface SearchResearchNotesRequest {
  workspaceId: string;
  query: string;
  includeArchived?: boolean;
  noteType?: NoteType;
  limit?: number;
}

export interface UpdateResearchWorkspaceRequest {
  workspaceId: string;
  name?: string;
  stage?: ResearchStage;
  defaultView?: WorkspaceViewKind;
  pinnedNoteIds?: string[];
}

export interface ArchiveResearchWorkspaceRequest {
  workspaceId: string;
  archived: boolean;
}
