import { beforeEach, describe, expect, it, vi } from 'vitest';
import { registerHost, __resetHostForTests, sendMessage } from '../state';
import type { StateHost } from '../state';
import type { Response } from '../messages';

function makeHost(response: { ok: boolean; error?: string }): StateHost {
  return {
    getState: () => ({ view: 'list' } as never),
    setState: vi.fn(),
    navigate: vi.fn(),
    sendMessage: vi.fn().mockResolvedValue(response as Response),
    escapeHtml: (s) => s,
    popOutToTab: vi.fn(),
    isInTab: () => false,
    openVaultTab: vi.fn(),
  };
}

describe('shared/state sendMessage vault_locked intercept', () => {
  beforeEach(() => __resetHostForTests());

  it('navigates to the lock screen on a vault_locked response', async () => {
    const host = makeHost({ ok: false, error: 'vault_locked' });
    registerHost(host);
    await sendMessage({ type: 'list_items' });
    expect(host.navigate).toHaveBeenCalledWith(
      'locked',
      expect.objectContaining({ error: expect.any(String) }),
    );
  });

  it('does NOT intercept the unlock request itself', async () => {
    const host = makeHost({ ok: false, error: 'vault_locked' });
    registerHost(host);
    await sendMessage({ type: 'unlock', passphrase: 'x' });
    expect(host.navigate).not.toHaveBeenCalled();
  });

  it('does NOT intercept is_unlocked', async () => {
    const host = makeHost({ ok: false, error: 'vault_locked' });
    registerHost(host);
    await sendMessage({ type: 'is_unlocked' });
    expect(host.navigate).not.toHaveBeenCalled();
  });

  it('does not intercept a successful response', async () => {
    const host = makeHost({ ok: true });
    registerHost(host);
    await sendMessage({ type: 'list_items' });
    expect(host.navigate).not.toHaveBeenCalled();
  });

  it('does not intercept a non-vault_locked error', async () => {
    const host = makeHost({ ok: false, error: 'something_else' });
    registerHost(host);
    await sendMessage({ type: 'list_items' });
    expect(host.navigate).not.toHaveBeenCalled();
  });

  it('returns the response unchanged', async () => {
    const host = makeHost({ ok: false, error: 'vault_locked' });
    registerHost(host);
    const resp = await sendMessage({ type: 'list_items' });
    expect(resp).toEqual({ ok: false, error: 'vault_locked' });
  });
});
