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';

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';

export type GhostTone = 'tentative';

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

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

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 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 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;
  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;
}

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 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[];
  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 CreateResearchWorkspaceRequest {
  name: string;
  primaryTicker: string;
  stage?: ResearchStage;
  defaultView?: WorkspaceViewKind;
}

export interface CaptureResearchNoteRequest {
  workspaceId: string;
  rawText: string;
  companyId?: string;
  ticker?: string;
  sourceRef?: SourceReferenceInput;
  positionHint?: string;
  userNoteTypeOverride?: NoteType;
}

export interface UpdateResearchNoteRequest {
  noteId: string;
  rawText?: 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 GetWorkspaceProjectionRequest {
  workspaceId: string;
  view?: WorkspaceViewKind;
}

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

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

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

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

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

export interface GetNoteAuditTrailRequest {
  noteId: string;
}

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;
}

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' },
];

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