import { describe, expect, it } from 'bun:test';
import {
  buildResearchWorkspaceSnapshotViewModel,
  filterSnapshotNotes,
  isSelectedNoteHidden,
} from './researchSelectors';
import type { ResearchNote, ResearchWorkspace, WorkspaceProjection } from '../types/research';

const workspace: ResearchWorkspace = {
  id: 'workspace-1',
  name: 'NVDA Research',
  primaryTicker: 'NVDA',
  scope: 'single_company',
  stage: 'capture',
  defaultView: 'canvas',
  pinnedNoteIds: ['stale-pinned-id'],
  archived: false,
  createdAt: '2026-04-09T10:00:00Z',
  updatedAt: '2026-04-09T10:00:00Z',
};

const note = (overrides: Partial<ResearchNote>): ResearchNote => ({
  id: 'note-1',
  workspaceId: workspace.id,
  rawText: 'Demand is improving.',
  cleanedText: 'Demand is improving.',
  embeds: [],
  fileIds: [],
  noteType: 'claim',
  analystStatus: 'captured',
  confidence: 0.7,
  evidenceStatus: 'source_linked',
  inferredLinks: [],
  ghostStatus: 'none',
  thesisStatus: 'none',
  createdAt: '2026-04-09T10:00:00Z',
  updatedAt: '2026-04-09T10:00:00Z',
  provenance: {
    createdBy: 'manual',
    captureMethod: 'quick_entry',
    sourceKind: 'manual',
    createdAt: '2026-04-09T10:00:00Z',
    rawInputHash: 'hash',
  },
  tags: [],
  catalysts: [],
  risks: [],
  valuationRefs: [],
  priority: 'normal',
  pinned: false,
  archived: false,
  revision: 1,
  ...overrides,
});

const snapshot: WorkspaceProjection = {
  workspace,
  activeView: 'canvas',
  notes: [
    note({ id: 'note-1', title: 'First note' }),
    note({ id: 'note-2', title: 'Second note', pinned: true }),
    note({ id: 'note-3', title: 'Archived note', archived: true }),
  ],
  links: [],
  ghosts: [],
  memoBlocks: [],
  graphNodes: [],
  graphEdges: [],
  kanbanColumns: [],
  timelineEvents: [],
};

describe('researchSelectors', () => {
  it('preserves server search ordering while resolving note objects from the snapshot', () => {
    const notes = filterSnapshotNotes(
      snapshot,
      {
        search: 'note',
        noteTypes: [],
        evidenceStatuses: [],
        showArchived: false,
        showGhosts: true,
      },
      ['note-2', 'note-1'],
    );

    expect(notes.map((current) => current.id)).toEqual(['note-2', 'note-1']);
  });

  it('detects when the selected note is hidden by current filters', () => {
    const visibleNotes = filterSnapshotNotes(
      snapshot,
      {
        search: '',
        noteTypes: [],
        evidenceStatuses: [],
        showArchived: false,
        showGhosts: true,
      },
      null,
    );

    expect(isSelectedNoteHidden(snapshot.notes[2], visibleNotes)).toBe(true);
  });

  it('derives pinned counts from canonical notes instead of stale workspace metadata', () => {
    const viewModel = buildResearchWorkspaceSnapshotViewModel(snapshot, []);

    expect(viewModel?.pinnedNoteCount).toBe(1);
  });
});
