import { strict as assert } from 'node:assert';
import { describe, it } from 'node:test';
import type { Database } from '@pig/db';
import { accounts, activities, agentTasks } from '@pig/db';
import { AuthError } from '../src/lib/auth';
import { executeMutation, MutationError } from '../src/lib/mutation';
import {
  accountSupportsTeam,
  createAccountMutationDefinition,
  createDemandDealMutationDefinition,
} from '../src/routes/records';
import { principal } from './helpers/principal';

const demandPrincipal = principal();

describe('record-side decisions', () => {
  it('makes dual-side accounts available to both commercial teams', () => {
    assert.equal(accountSupportsTeam('both', 'demand'), true);
    assert.equal(accountSupportsTeam('both', 'supply'), true);
    assert.equal(accountSupportsTeam('both', 'research'), false);
    assert.equal(accountSupportsTeam('supply', 'demand'), false);
    assert.equal(accountSupportsTeam('demand', 'supply'), false);
  });

  it('does not let a demand writer create a supply-only account', async () => {
    const db = {
      transaction: async (work: (tx: unknown) => Promise<unknown>) => work({}),
    } as unknown as Database;

    await assert.rejects(
      executeMutation(
        db,
        demandPrincipal,
        async () => ({
          name: 'Supply only',
          side: 'supply',
        }),
        createAccountMutationDefinition(),
      ),
      (error: unknown) =>
        error instanceof AuthError && error.code === 'insufficient_permission',
    );
  });
});

describe('record mutation evidence and relationships', () => {
  it('queues enrichment and writes the audit event in the account transaction', async () => {
    const events: string[] = [];
    const created = {
      id: '10000000-0000-4000-8000-000000000001',
      name: 'Customer',
      side: 'demand',
    };
    const tx = {
      insert: (table: unknown) => ({
        values: (row: unknown) => {
          events.push(
            table === accounts ? 'account' : table === agentTasks ? 'agent-task' : table === activities ? 'activity' : 'unknown',
          );
          return { returning: async () => [created], row };
        },
      }),
    };
    const db = {
      transaction: async (work: (transaction: unknown) => Promise<unknown>) => {
        events.push('begin');
        const result = await work(tx);
        events.push('commit');
        return result;
      },
    } as unknown as Database;

    await executeMutation(
      db,
      demandPrincipal,
      async () => ({ name: 'Customer', side: 'demand' }),
      createAccountMutationDefinition(),
    );

    assert.deepEqual(events, ['begin', 'account', 'agent-task', 'activity', 'commit']);
  });

  it('rejects a demand deal attached to a supply-only account', async () => {
    const tx = {
      select: () => ({
        from: () => ({
          where: () => ({
            limit: async () => [{ id: '10000000-0000-4000-8000-000000000001', side: 'supply' }],
          }),
        }),
      }),
    };
    const db = {
      transaction: async (work: (transaction: unknown) => Promise<unknown>) => work(tx),
    } as unknown as Database;

    await assert.rejects(
      executeMutation(
        db,
        demandPrincipal,
        async () => ({
          accountId: '10000000-0000-4000-8000-000000000001',
          name: 'Impossible relationship',
          productLine: 'compute_reserved',
          stage: 'qualification',
          currency: 'USD',
          msaExecuted: false,
          dpaExecuted: false,
        }),
        createDemandDealMutationDefinition(),
      ),
      (error: unknown) =>
        error instanceof MutationError && error.code === 'relationship_mismatch',
    );
  });
});
