import { DEMAND_STAGES } from '@pig/core';
import type { Database } from '@pig/db';
import { demandDeals } from '@pig/db';
import { eq } from 'drizzle-orm';
import { z } from 'zod';
import { MutationError, mutation } from '../lib/mutation';
import type { NotificationOutbox } from '../services/notification-outbox';

const demandStageMutationSchema = z
  .object({ stage: z.enum(DEMAND_STAGES) })
  .strict();

/**
 * Stage transitions and their audit evidence commit together, so a pipeline
 * review can never see a new stage without who changed it and when.
 */
export function createDemandStageMutation(db: Database, notifications?: NotificationOutbox) {
  return mutation(db, {
    schema: demandStageMutationSchema,
    permission: { capability: 'deal:write', team: 'demand' },
    invalidMessage: 'Invalid demand stage transition.',
    async mutate({ input, params, tx, now }) {
      const id = params.id;
      if (!id) throw MutationError.notFound('Demand deal');
      const [before] = await tx.select().from(demandDeals).where(eq(demandDeals.id, id)).limit(1);
      if (!before) throw MutationError.notFound('Demand deal');

      const [updated] = await tx
        .update(demandDeals)
        .set({
          stage: input.stage,
          stageChangedAt: now,
          updatedAt: now,
          lastActivityAt: now,
        })
        .where(eq(demandDeals.id, id))
        .returning();
      if (!updated) throw MutationError.notFound('Demand deal');
      await notifications?.enqueueStageChange(tx, {
        accountId: before.accountId,
        dealId: before.id,
        dealSide: 'demand',
        dealName: before.name,
        fromStage: before.stage,
        toStage: input.stage,
        changedAt: now.toISOString(),
      });
      return {
        data: updated,
        activity: {
          type: 'stage_change',
          subject: `${before.stage} → ${input.stage}`,
          accountId: before.accountId,
          demandDealId: before.id,
          meta: { from: before.stage, to: input.stage },
        },
      };
    },
  });
}
