import { z } from 'zod';
import type { FactoryOperationHandler } from './core';

export const FACTORY_OPERATIONS = [
  'createActor',
  'createVendor',
  'createVendorAddress',
  'createDealCategory',
  'createDeal',
  'createPurchase',
  'adoptPurchase',
  'adoptPersonalDealRequest',
  'createLlmJob',
  'processLlmJob',
  'createLlmProvider',
  'createPromotion',
  'createActorAddress',
  'createEmailVerification',
  'createImageUpload',
  'createMailCapture',
  'adoptRegisteredActor',
  'adoptVendorRegistration',
  'adoptVendorUpgrade',
  'createOtpRegistrationProof',
  'adoptDeal',
  'emitVendorAccountUpdated',
  'processImageRejection',
  'setActorAccountState',
  'setDealSkuActive',
  'updateActorProfile',
  'attributeAffiliateReferral',
  'startAffiliateConnectOnboarding',
  'completeAffiliatePayoutConnection',
  'verifyAffiliateKyc',
  'createAffiliateFraudEvent',
  'applyAffiliateFraudClawback',
  'settleAffiliatePayout',
] as const;

export const FACTORY_ENTITY_KINDS = [
  'actor',
  'vendor',
  'vendor-address',
  'deal-category',
  'deal',
  'purchase',
  'promotion',
  'llm-job',
  'llm-provider',
  'image-upload',
  'email-verification',
  'mail-capture',
  'personal-deal-request',
  'otp-registration',
] as const;

export const factoryOperationSchema = z.enum(FACTORY_OPERATIONS);
export const factoryEntityKindSchema = z.enum(FACTORY_ENTITY_KINDS);

export type FactoryOperation = z.infer<typeof factoryOperationSchema>;
export type FactoryEntityKind = z.infer<typeof factoryEntityKindSchema>;

export function assertFactoryHandlerContract(
  handlers: Record<string, FactoryOperationHandler>,
): asserts handlers is Record<FactoryOperation, FactoryOperationHandler> {
  const expected = new Set<string>(FACTORY_OPERATIONS);
  const missing = FACTORY_OPERATIONS.filter((operation) => !handlers[operation]);
  const extra = Object.keys(handlers).filter((operation) => !expected.has(operation));
  if (missing.length || extra.length) {
    throw new Error(
      `Factory handler contract drift: missing=[${missing.join(',')}], extra=[${extra.join(',')}]`,
    );
  }
}
