/**
 * updateUser persists the optional signing-identity override
 * (user_profiles.signing_email): lowercased on the way in, and cleared to NULL
 * when an empty string is supplied.
 */
import { afterAll, describe, expect, it, vi } from 'vitest';
import { eq } from 'drizzle-orm';

import { db } from '@/lib/db';
import { account, roles, user, userProfiles } from '@/lib/db/schema';
import { auth } from '@/lib/auth';
import { createUser, updateUser } from '@/lib/services/users.service';
import { makePort, makeAuditMeta } from '../helpers/factories';

describe('updateUser - signing_email override', () => {
  const createdUserIds: string[] = [];

  afterAll(async () => {
    for (const id of createdUserIds) {
      await db.delete(account).where(eq(account.userId, id));
      await db.delete(userProfiles).where(eq(userProfiles.userId, id));
      await db.delete(user).where(eq(user.id, id));
    }
  });

  async function makeUser(): Promise<{ userId: string; portId: string }> {
    const resetSpy = vi
      .spyOn(auth.api, 'requestPasswordReset')
      .mockResolvedValue({ status: true } as never);
    try {
      const port = await makePort();
      const role = await db.query.roles.findFirst({ where: eq(roles.name, 'sales_manager') });
      if (!role) throw new Error('sales_manager role not seeded');
      const created = await createUser(
        port.id,
        {
          email: `signemail-${Date.now()}-${Math.random().toString(36).slice(2, 6)}@example.test`,
          name: 'Abbie May',
          displayName: 'Abbie May',
          roleId: role.id,
          sendSetupEmail: true,
          residentialAccess: false,
        },
        makeAuditMeta(),
      );
      createdUserIds.push(created.userId);
      return { userId: created.userId, portId: port.id };
    } finally {
      resetSpy.mockRestore();
    }
  }

  async function readSigningEmail(userId: string): Promise<string | null> {
    const row = await db.query.userProfiles.findFirst({
      where: eq(userProfiles.userId, userId),
    });
    return row?.signingEmail ?? null;
  }

  it('persists a signing email, lowercased', async () => {
    const { userId, portId } = await makeUser();

    await updateUser(userId, portId, { signingEmail: 'SALES@PortNimara.com' }, makeAuditMeta());

    expect(await readSigningEmail(userId)).toBe('sales@portnimara.com');
  });

  it('clears the override when an empty string is supplied', async () => {
    const { userId, portId } = await makeUser();
    await updateUser(userId, portId, { signingEmail: 'sales@portnimara.com' }, makeAuditMeta());
    expect(await readSigningEmail(userId)).toBe('sales@portnimara.com');

    await updateUser(userId, portId, { signingEmail: '' }, makeAuditMeta());

    expect(await readSigningEmail(userId)).toBeNull();
  });
});
