import { describe, expect, it, vi } from 'vitest';
import { PgProfileRepository } from './pg-profile-repository.js';

interface QueryResult {
  rows: unknown[];
}

/** F-154: mock pg.Pool returning configurable rows keyed by SQL family. */
function mockPool(countRows: unknown[], selectRows: unknown[]) {
  const query = vi.fn(async (sql: string, _params: unknown[]): Promise<QueryResult> => {
    if (String(sql).includes('COUNT')) return { rows: countRows };
    return { rows: selectRows };
  });
  const pool = { query } as unknown as import('pg').Pool;
  return { pool, query };
}

const CUSTOMER_ROW = {
  user_id: 'c1',
  email: 'ben@example.com',
  role: 'customer',
  display_name: 'Ben',
  phone: '111',
  created_at: new Date('2026-01-01T00:00:00Z'),
};

describe('PgProfileRepository.listCustomers — F-154 customers-only', () => {
  it('always restricts the list query to role = customer', async () => {
    const { pool, query } = mockPool([{ cnt: '1' }], [CUSTOMER_ROW]);
    const repo = new PgProfileRepository(pool);

    const result = await repo.listCustomers({ offset: 0, limit: 20 });

    expect(result.total).toBe(1);
    expect(result.items).toHaveLength(1);
    expect(result.items[0]!.role).toBe('customer');
    expect(result.items[0]!.email).toBe('ben@example.com');

    const selectSql = query.mock.calls[1]![0] as string;
    expect(selectSql).toContain("iu.role = 'customer'");
  });

  it('applies the customer filter to the count query too', async () => {
    const { pool, query } = mockPool([{ cnt: '1' }], [CUSTOMER_ROW]);
    const repo = new PgProfileRepository(pool);

    await repo.listCustomers({ offset: 0, limit: 20 });

    const countSql = query.mock.calls[0]![0] as string;
    expect(countSql).toContain('COUNT');
    expect(countSql).toContain("iu.role = 'customer'");
  });

  it('keeps the email search parameterized alongside the role filter', async () => {
    const { pool, query } = mockPool([{ cnt: '1' }], [CUSTOMER_ROW]);
    const repo = new PgProfileRepository(pool);

    await repo.listCustomers({ q: 'ben', offset: 0, limit: 20 });

    const selectSql = query.mock.calls[1]![0] as string;
    const params = query.mock.calls[1]![1] as unknown[];
    expect(selectSql).toContain("iu.role = 'customer'");
    expect(selectSql).toContain('ILIKE $1');
    expect(params[0]).toBe('%ben%');
  });
});
