/**
 * i18n PR9–10 - public residential inquiry endpoint.
 *
 * Validates the server-side phone normalization that the public inquiry
 * route runs when the website posts a raw international format (older
 * Nuxt builds), and that pre-normalized payloads pass through unchanged.
 */

import { describe, it, expect, vi, beforeAll } from 'vitest';
import { eq } from 'drizzle-orm';

import { db } from '@/lib/db';
import { residentialClients } from '@/lib/db/schema/residential';
import { disableResidentialModule } from '@/lib/services/residential-module.service';
import { makePort } from '../helpers/factories';
import { makeMockRequest } from '../helpers/route-tester';

vi.mock('@/lib/socket/server', () => ({ emitToRoom: vi.fn() }));
vi.mock('@/lib/email', () => ({ sendEmail: vi.fn().mockResolvedValue(undefined) }));

// Randomize per-run prefix so leftover redis sliding-window entries from a
// previous run don't 429 the new run (publicForm limiter pexpires after 1h).
const IP_PREFIX = `10.${Math.floor(Math.random() * 200) + 10}`;
let ipCounter = 1;
function uniqueIp(): string {
  ipCounter += 1;
  return `${IP_PREFIX}.${Math.floor(ipCounter / 255) % 255}.${ipCounter % 255}`;
}

describe('POST /api/public/residential-inquiries', () => {
  let POST: typeof import('@/app/api/public/residential-inquiries/route').POST;

  beforeAll(async () => {
    const mod = await import('@/app/api/public/residential-inquiries/route');
    POST = mod.POST;
  });

  it('parses a raw international phone string into E.164 + country', async () => {
    const port = await makePort();
    const email = `res-${Math.random().toString(36).slice(2, 8)}@test.local`;

    const req = makeMockRequest(
      'POST',
      `http://localhost/api/public/residential-inquiries?portId=${port.id}`,
      {
        headers: { 'x-forwarded-for': uniqueIp() },
        body: {
          firstName: 'Anna',
          lastName: 'Nowak',
          email,
          // Raw international format - server should normalize.
          phone: '+44 20 7946 0958',
          placeOfResidence: 'Warsaw',
        },
      },
    );

    const res = await POST(req);
    expect(res.status).toBe(201);

    const [row] = await db
      .select()
      .from(residentialClients)
      .where(eq(residentialClients.email, email));

    expect(row).toBeDefined();
    expect(row?.phoneE164).toBe('+442079460958');
    expect(row?.phoneCountry).toBe('GB');
    // Free-text legacy column preserved verbatim for backfill.
    expect(row?.phone).toBe('+44 20 7946 0958');
  });

  it('passes pre-normalized E.164 + country through unchanged', async () => {
    const port = await makePort();
    const email = `res-${Math.random().toString(36).slice(2, 8)}@test.local`;

    const req = makeMockRequest(
      'POST',
      `http://localhost/api/public/residential-inquiries?portId=${port.id}`,
      {
        headers: { 'x-forwarded-for': uniqueIp() },
        body: {
          firstName: 'Jan',
          lastName: 'Kowalski',
          email,
          phone: '+48 22 555 0100',
          phoneE164: '+48225550100',
          phoneCountry: 'PL',
          nationalityIso: 'PL',
          timezone: 'Europe/Warsaw',
          placeOfResidence: 'Warsaw',
          placeOfResidenceCountryIso: 'PL',
        },
      },
    );

    const res = await POST(req);
    expect(res.status).toBe(201);

    const [row] = await db
      .select()
      .from(residentialClients)
      .where(eq(residentialClients.email, email));

    expect(row?.phoneE164).toBe('+48225550100');
    expect(row?.phoneCountry).toBe('PL');
    expect(row?.nationalityIso).toBe('PL');
    expect(row?.timezone).toBe('Europe/Warsaw');
    expect(row?.placeOfResidenceCountryIso).toBe('PL');
  });

  it('persists a national-format phone when the website only sends a country hint', async () => {
    const port = await makePort();
    const email = `res-${Math.random().toString(36).slice(2, 8)}@test.local`;

    const req = makeMockRequest(
      'POST',
      `http://localhost/api/public/residential-inquiries?portId=${port.id}`,
      {
        headers: { 'x-forwarded-for': uniqueIp() },
        body: {
          firstName: 'Marta',
          lastName: 'Lewandowska',
          email,
          phone: '22 555 0200', // National-format
          phoneCountry: 'PL', // Hint only - no E.164 yet.
        },
      },
    );

    const res = await POST(req);
    expect(res.status).toBe(201);

    const [row] = await db
      .select()
      .from(residentialClients)
      .where(eq(residentialClients.email, email));

    expect(row?.phoneE164).toBe('+48225550200');
    expect(row?.phoneCountry).toBe('PL');
  });

  it('rejects the inquiry when the port has the Residential module disabled', async () => {
    const port = await makePort();
    await disableResidentialModule(port.id);
    const email = `res-${Math.random().toString(36).slice(2, 8)}@test.local`;

    const req = makeMockRequest(
      'POST',
      `http://localhost/api/public/residential-inquiries?portId=${port.id}`,
      {
        headers: { 'x-forwarded-for': uniqueIp() },
        body: {
          firstName: 'Ola',
          lastName: 'Disabled',
          email,
          phone: '+48 22 555 0300',
          placeOfResidence: 'Warsaw',
        },
      },
    );

    const res = await POST(req);
    // Module gate maps NotFoundError → 404; no client row should be written.
    expect(res.status).toBe(404);

    const rows = await db
      .select()
      .from(residentialClients)
      .where(eq(residentialClients.email, email));
    expect(rows).toHaveLength(0);
  });
});
