import { describe, expect, it, vi } from 'vitest';
import { PgOrderRepository } from './pg-order-repository.js';
import type { OrderView } from '../domain/order.js';

/** F-153: mock mínimo de pg.Pool que discrimina por SQL (ordenes vs items). */
function mockPool(orderRow: Record<string, unknown> | null, itemRows: unknown[] = []) {
  const query = vi.fn((sql: string) => {
    const text = String(sql);
    if (text.includes('orders_items')) return Promise.resolve({ rows: itemRows });
    return Promise.resolve({ rows: orderRow ? [orderRow] : [] });
  });
  const pool = { query } as unknown as import('pg').Pool;
  return { pool, query };
}

const BASE_ORDER = {
  id: 'order-1',
  user_id: 'user-1',
  idempotency_key: null,
  state: 'PENDING',
  currency: 'EUR',
  subtotal_cents: 1000,
  discount_cents: 0,
  tax_cents: 210,
  total_cents: 1210,
  tracking_number: null,
  courier: null,
  customer_name: null,
  customer_phone: null,
  phone: null,
  created_at: new Date('2026-01-01T00:00:00Z'),
  updated_at: new Date('2026-01-01T00:00:00Z'),
};

describe('PgOrderRepository.findById — F-153 customer email association', () => {
  it('resolves customer email through the identity_users join', async () => {
    const { pool, query } = mockPool({ ...BASE_ORDER, email: 'customer@example.com' });
    const repo = new PgOrderRepository(pool);

    const result: OrderView | undefined = await repo.findById('order-1');

    expect(result).toBeDefined();
    expect(result!.email).toBe('customer@example.com');
    const orderQuery = String(query.mock.calls[0]![0]);
    expect(orderQuery).toContain('identity_users');
    expect(orderQuery).toContain('users_profiles');
    expect(orderQuery).toContain('COALESCE(o.customer_name, p.display_name)');
    expect(orderQuery).toContain('u.email');
  });

  it('maps customer name and phone resolved by the read query', async () => {
    const { pool } = mockPool({
      ...BASE_ORDER,
      email: 'customer@example.com',
      customer_name: 'Cliente Ejemplo',
      customer_phone: '+34600000000',
      phone: '+34600000000',
    });
    const repo = new PgOrderRepository(pool);

    const result = await repo.findById('order-1');

    expect(result?.customerName).toBe('Cliente Ejemplo');
    expect(result?.customerPhone).toBe('+34600000000');
    expect(result?.phone).toBe('+34600000000');
  });

  it('returns null email when the order has no linked identity_user', async () => {
    const { pool } = mockPool({ ...BASE_ORDER, email: null });
    const repo = new PgOrderRepository(pool);

    const result = await repo.findById('order-1');

    expect(result).toBeDefined();
    expect(result!.email).toBeNull();
  });

  it('returns undefined when the order does not exist', async () => {
    const { pool } = mockPool(null);
    const repo = new PgOrderRepository(pool);

    const result = await repo.findById('missing');

    expect(result).toBeUndefined();
  });
});
