/**
 * The EOI signer slot, when linked to a CRM user, resolves that user's
 * SIGNING identity — `user_profiles.signing_email` when set, otherwise the
 * login `user.email`. This lets a person who logs in as `abbie@` sign on
 * behalf of the shared `sales@` role mailbox without changing their login.
 */
import { afterAll, describe, expect, it, vi } from 'vitest';
import { eq } from 'drizzle-orm';

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

describe('getPortEoiSigners - 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 salesRoleId(): Promise<string> {
    const r = await db.query.roles.findFirst({ where: eq(roles.name, 'sales_manager') });
    if (!r) throw new Error('sales_manager role not seeded — run pnpm db:seed');
    return r.id;
  }

  async function makeSignerUser(loginEmail: string): Promise<string> {
    const resetSpy = vi
      .spyOn(auth.api, 'requestPasswordReset')
      .mockResolvedValue({ status: true } as never);
    try {
      const port = await makePort();
      const created = await createUser(
        port.id,
        {
          email: loginEmail,
          name: 'Abbie May',
          displayName: 'Abbie May',
          roleId: await salesRoleId(),
          sendSetupEmail: true,
          residentialAccess: false,
        },
        makeAuditMeta(),
      );
      createdUserIds.push(created.userId);
      return created.userId;
    } finally {
      resetSpy.mockRestore();
    }
  }

  it('resolves the linked signer email from signing_email when set', async () => {
    const port = await makePort();
    const userId = await makeSignerUser(`login-${Date.now()}-a@example.test`);
    await db
      .update(userProfiles)
      .set({ signingEmail: 'sales@portnimara.com' })
      .where(eq(userProfiles.userId, userId));
    await db
      .insert(systemSettings)
      .values({ portId: port.id, key: 'documenso_approver_user_id', value: userId });

    const signers = await getPortEoiSigners(port.id);

    expect(signers.approver.email).toBe('sales@portnimara.com');
    expect(signers.approver.name).toBe('Abbie May');
  });

  it('falls back to the login email when signing_email is null', async () => {
    const port = await makePort();
    const loginEmail = `login-${Date.now()}-b@example.test`;
    const userId = await makeSignerUser(loginEmail);
    await db
      .insert(systemSettings)
      .values({ portId: port.id, key: 'documenso_approver_user_id', value: userId });

    const signers = await getPortEoiSigners(port.id);

    expect(signers.approver.email).toBe(loginEmail);
  });
});
