import { describe, expect, it } from 'vitest';
import { handleGetVaultStatus } from '../vault';
import type { Manifest, ManifestEntry } from '../../shared/types';

// The handler only reads gitHost's three cache fields, so the test feeds a
// minimal object — the handler's Pick-typed param makes full GitHost mocking
// unnecessary.
const cache = (lastSyncAt: number | null, ahead = 0, behind = 0) =>
  ({ lastSyncAt, ahead, behind });

function manifestWith(activeCount: number, trashedCount = 0): Manifest {
  const items: Record<string, ManifestEntry> = {};
  for (let i = 0; i < activeCount; i++) {
    items[`a${i}`] = { trashed_at: undefined } as ManifestEntry;
  }
  for (let i = 0; i < trashedCount; i++) {
    items[`t${i}`] = { trashed_at: 1000 } as ManifestEntry;
  }
  return { items } as Manifest;
}

describe('handleGetVaultStatus', () => {
  it('returns zeros when never synced and no manifest', () => {
    const resp = handleGetVaultStatus({ gitHost: cache(null), manifest: null });
    expect(resp).toEqual({
      ok: true,
      data: { ahead: 0, behind: 0, lastSyncAt: null, pendingItems: 0 },
    });
  });

  it('reflects cached sync state + active (non-trashed) item count', () => {
    const resp = handleGetVaultStatus({
      gitHost: cache(1234567890, 3, 1),
      manifest: manifestWith(5, 2),
    });
    expect(resp.ok).toBe(true);
    if (resp.ok) {
      expect(resp.data).toEqual({
        ahead: 3, behind: 1, lastSyncAt: 1234567890, pendingItems: 5,
      });
    }
  });

  it('returns vault_locked error when gitHost is null', () => {
    expect(handleGetVaultStatus({ gitHost: null, manifest: null }))
      .toEqual({ ok: false, error: 'vault_locked' });
  });

  it('is synchronous — no network round-trip', () => {
    const resp = handleGetVaultStatus({ gitHost: cache(0), manifest: null });
    expect(resp).not.toBeInstanceOf(Promise);
  });
});
