import { researchBridge } from '../lib/researchBridge';
import type {
  ArchiveResearchNoteRequest,
  ArchiveResearchWorkspaceRequest,
  CaptureResearchNoteRequest,
  CreateFinancialModelRequest,
  CreateResearchWorkspaceRequest,
  EvaluateFinancialModelRequest,
  EvaluateFinancialModelResult,
  ExportFinancialModelXlsxRequest,
  ExportFinancialModelXlsxResult,
  FinancialModel,
  GetFinancialModelRequest,
  GetNoteAuditTrailRequest,
  GetResearchFileTextPreviewRequest,
  GhostNote,
  ListResearchFilesRequest,
  ListResearchJobsRequest,
  ListFinancialModelsRequest,
  ListModelCellAnnotationsRequest,
  ListModelDataBindingsRequest,
  LinkNoteToModelCellRequest,
  ModelCellAnnotation,
  ModelDataBinding,
  NoteAuditTrail,
  NoteCaptureResult,
  PipelineJob,
  PreviewLinkRequest,
  PreviewLinkResult,
  PromoteNoteToThesisRequest,
  ResearchGhostUpdateEvent,
  ResearchFile,
  ResearchFileTextPreview,
  ResearchJobUpdateEvent,
  ResearchNavigationIntent,
  ResearchNote,
  ResearchNoteUpdateEvent,
  ResearchWorkspace,
  ResearchWorkspaceUpdateEvent,
  RetryResearchJobsRequest,
  ResolveGhostInterventionRequest,
  ReviewGhostNoteRequest,
  SaveFinancialModelRequest,
  SaveModelDataBindingRequest,
  SearchResearchNotesRequest,
  RefreshModelDataBindingsRequest,
  UnlinkNoteFromModelCellRequest,
  UpdateModelCellAnnotationRequest,
  UpdateResearchNoteRequest,
  UpdateResearchWorkspaceRequest,
  UploadResearchFilesRequest,
  WorkspaceProjection,
} from '../types/research';

export interface SearchResearchNoteIdsRequest {
  workspaceId: string;
  query: string;
  includeArchived?: boolean;
}

export const normalizeResearchSearchQuery = (query: string) => query.trim();

export const researchApi = {
  listWorkspaces(): Promise<ResearchWorkspace[]> {
    return researchBridge.listResearchWorkspaces();
  },

  getWorkspaceSnapshot(workspaceId: string): Promise<WorkspaceProjection> {
    return researchBridge.getWorkspaceProjection({ workspaceId });
  },

  listFinancialModels(request: ListFinancialModelsRequest): Promise<FinancialModel[]> {
    return researchBridge.listFinancialModels(request);
  },

  getFinancialModel(request: GetFinancialModelRequest): Promise<FinancialModel> {
    return researchBridge.getFinancialModel(request);
  },

  createFinancialModel(request: CreateFinancialModelRequest): Promise<FinancialModel> {
    return researchBridge.createFinancialModel(request);
  },

  saveFinancialModel(request: SaveFinancialModelRequest): Promise<FinancialModel> {
    return researchBridge.saveFinancialModel(request);
  },

  evaluateFinancialModel(
    request: EvaluateFinancialModelRequest,
  ): Promise<EvaluateFinancialModelResult> {
    return researchBridge.evaluateFinancialModel(request);
  },

  listModelDataBindings(
    request: ListModelDataBindingsRequest,
  ): Promise<ModelDataBinding[]> {
    return researchBridge.listModelDataBindings(request);
  },

  saveModelDataBinding(request: SaveModelDataBindingRequest): Promise<ModelDataBinding> {
    return researchBridge.saveModelDataBinding(request);
  },

  refreshModelDataBindings(
    request: RefreshModelDataBindingsRequest,
  ): Promise<ModelDataBinding[]> {
    return researchBridge.refreshModelDataBindings(request);
  },

  linkNoteToModelCell(request: LinkNoteToModelCellRequest): Promise<ModelCellAnnotation> {
    return researchBridge.linkNoteToModelCell(request);
  },

  unlinkNoteFromModelCell(
    request: UnlinkNoteFromModelCellRequest,
  ): Promise<ModelCellAnnotation> {
    return researchBridge.unlinkNoteFromModelCell(request);
  },

  updateModelCellAnnotation(
    request: UpdateModelCellAnnotationRequest,
  ): Promise<ModelCellAnnotation> {
    return researchBridge.updateModelCellAnnotation(request);
  },

  listModelCellAnnotations(
    request: ListModelCellAnnotationsRequest,
  ): Promise<ModelCellAnnotation[]> {
    return researchBridge.listModelCellAnnotations(request);
  },

  exportFinancialModelXlsx(
    request: ExportFinancialModelXlsxRequest,
  ): Promise<ExportFinancialModelXlsxResult> {
    return researchBridge.exportFinancialModelXlsx(request);
  },

  listJobs(request: ListResearchJobsRequest): Promise<PipelineJob[]> {
    return researchBridge.listResearchJobs(request);
  },

  createWorkspace(request: CreateResearchWorkspaceRequest): Promise<ResearchWorkspace> {
    return researchBridge.createResearchWorkspace(request);
  },

  updateWorkspace(request: UpdateResearchWorkspaceRequest): Promise<ResearchWorkspace> {
    return researchBridge.updateResearchWorkspace(request);
  },

  archiveWorkspace(request: ArchiveResearchWorkspaceRequest): Promise<ResearchWorkspace> {
    return researchBridge.archiveResearchWorkspace(request);
  },

  captureNote(request: CaptureResearchNoteRequest): Promise<NoteCaptureResult> {
    return researchBridge.captureResearchNote(request);
  },

  previewLink(request: PreviewLinkRequest): Promise<PreviewLinkResult> {
    return researchBridge.previewNoteLink(request);
  },

  updateNote(request: UpdateResearchNoteRequest): Promise<ResearchNote> {
    return researchBridge.updateResearchNote(request);
  },

  archiveNote(request: ArchiveResearchNoteRequest): Promise<ResearchNote> {
    return researchBridge.archiveResearchNote(request);
  },

  promoteNote(request: PromoteNoteToThesisRequest): Promise<ResearchNote> {
    return researchBridge.promoteNoteToThesis(request);
  },

  reviewGhost(request: ReviewGhostNoteRequest): Promise<GhostNote> {
    return researchBridge.reviewGhostNote(request);
  },

  resolveGhostIntervention(request: ResolveGhostInterventionRequest): Promise<GhostNote> {
    return researchBridge.resolveGhostIntervention(request);
  },

  retryJobs(request: RetryResearchJobsRequest): Promise<PipelineJob[]> {
    return researchBridge.retryResearchJobs(request);
  },

  getNoteAuditTrail(request: GetNoteAuditTrailRequest): Promise<NoteAuditTrail> {
    return researchBridge.getNoteAuditTrail(request);
  },

  listFiles(request: ListResearchFilesRequest): Promise<ResearchFile[]> {
    return researchBridge.listResearchFiles(request);
  },

  uploadFiles(request: UploadResearchFilesRequest): Promise<ResearchFile[]> {
    return researchBridge.uploadResearchFiles(request);
  },

  getTextPreview(
    request: GetResearchFileTextPreviewRequest,
  ): Promise<ResearchFileTextPreview> {
    return researchBridge.getResearchFileTextPreview(request);
  },

  async searchNoteIds(request: SearchResearchNoteIdsRequest): Promise<string[]> {
    const normalizedQuery = normalizeResearchSearchQuery(request.query);
    if (!normalizedQuery) {
      return [];
    }

    const results = await researchBridge.searchResearchNotes({
      workspaceId: request.workspaceId,
      query: normalizedQuery,
      includeArchived: request.includeArchived,
    } satisfies SearchResearchNotesRequest);

    return results.map((note) => note.id);
  },

  listenForWorkspaceUpdates(
    handler: (payload: ResearchWorkspaceUpdateEvent) => void,
  ): Promise<() => void> {
    return researchBridge.listenForWorkspaceUpdates(handler);
  },

  listenForNoteUpdates(
    handler: (payload: ResearchNoteUpdateEvent) => void,
  ): Promise<() => void> {
    return researchBridge.listenForNoteUpdates(handler);
  },

  listenForGhostUpdates(
    handler: (payload: ResearchGhostUpdateEvent) => void,
  ): Promise<() => void> {
    return researchBridge.listenForGhostUpdates(handler);
  },

  listenForJobUpdates(
    handler: (payload: ResearchJobUpdateEvent) => void,
  ): Promise<() => void> {
    return researchBridge.listenForJobUpdates(handler);
  },
};

export const isResearchIntentEmpty = (intent: ResearchNavigationIntent | null | undefined) =>
  !intent ||
  (!intent.ticker &&
    !intent.workspaceId &&
    !intent.preferredView &&
    !intent.seedNote &&
    !intent.terminalNoteSeed);
