import { describe, it, expect, beforeEach, vi } from 'vitest';
import type { Note } from '@shared/types';

const mockApi = {
  listNotes: vi.fn(async () => [] as Note[]),
  listTrash: vi.fn(async () => [] as Note[]),
  listByStatus: vi.fn(async () => [] as Note[]),
  countsByStatus: vi.fn(async () => ({ active: 0, completed: 0, archived: 0, trashed: 0 })),
  getTrashCount: vi.fn(async () => 0),
  getContinuity: vi.fn(async () => ({
    weekStart: '', weekCount: 0, weekTarget: 7,
    consecutiveCompleteWeeks: 0, showRecoveryToast: false, lastNoteAt: null
  })),
  getPendingCount: vi.fn(async () => 0),
  getOllamaStatus: vi.fn(async () => ({ ok: true })),
  getTodayCount: vi.fn(async () => 0),
  getFailedCount: vi.fn(async () => 0),
  listExpired: vi.fn(async () => [] as Note[]),
  listRecallCandidate: vi.fn(async () => null),
  restoreNote: vi.fn(async () => {}),
  permanentDeleteNote: vi.fn(async () => ({ confirmed: true })),
  emptyTrash: vi.fn(async () => ({ confirmed: true, count: 0 })),
  trashExpiredBatch: vi.fn(async () => ({ confirmed: true, trashedCount: 0 })),
  onNoteUpdated: vi.fn(() => () => {}),
  updateAiFields: vi.fn(async () => {}),
  setDueDate: vi.fn(async () => {}),
  setIntent: vi.fn(async () => {}),
  dismissIntent: vi.fn(async () => {}),
  ollamaRecheck: vi.fn(async () => ({ ok: true })),
  retryAllFailed: vi.fn(async () => {}),
  markRecallOpened: vi.fn(async () => {}),
  dismissRecall: vi.fn(async () => {}),
  emitRecallSnoozed: vi.fn(async () => {})
};

vi.mock('../../src/renderer/inbox/api.js', () => ({ inboxApi: mockApi }));

describe('inbox store — view enum', () => {
  beforeEach(async () => {
    const { useInbox } = await import('../../src/renderer/inbox/store.js');
    useInbox.setState({
      view: 'inbox',
      counts: { active: 0, completed: 0, archived: 0, trashed: 0 },
      notes: [], trashNotes: [], trashCount: 0,
      showTrash: false, showSettings: false,
      loading: false, tagFilter: null, pendingCount: 0, todayCount: 0,
      ollamaStatus: { ok: true },
      continuity: { weekStart: '', weekCount: 0, weekTarget: 7, consecutiveCompleteWeeks: 0, showRecoveryToast: false, lastNoteAt: null },
      expiredCandidates: [], expiredSnoozeUntilMs: null,
      failedCount: 0, recallCandidate: null, recallSnoozeUntilMs: null
    });
    Object.values(mockApi).forEach((fn) => 'mockClear' in fn && (fn as any).mockClear());
  });

  it('initial view is inbox', async () => {
    const { useInbox } = await import('../../src/renderer/inbox/store.js');
    expect(useInbox.getState().view).toBe('inbox');
  });

  it('setView changes view', async () => {
    const { useInbox } = await import('../../src/renderer/inbox/store.js');
    useInbox.getState().setView('completed');
    expect(useInbox.getState().view).toBe('completed');
  });

  it('counts initialized to zero per status', async () => {
    const { useInbox } = await import('../../src/renderer/inbox/store.js');
    expect(useInbox.getState().counts).toEqual({ active: 0, completed: 0, archived: 0, trashed: 0 });
  });

  it('backward-compat: showTrash mirrors view==="trash"', async () => {
    const { useInbox } = await import('../../src/renderer/inbox/store.js');
    useInbox.getState().setView('trash');
    expect(useInbox.getState().showTrash).toBe(true);
    useInbox.getState().setView('inbox');
    expect(useInbox.getState().showTrash).toBe(false);
  });

  it('backward-compat: showSettings mirrors view==="settings"', async () => {
    const { useInbox } = await import('../../src/renderer/inbox/store.js');
    useInbox.getState().setView('settings');
    expect(useInbox.getState().showSettings).toBe(true);
    useInbox.getState().setView('inbox');
    expect(useInbox.getState().showSettings).toBe(false);
  });
});
