import { z } from 'zod';
import type {
  EventChoice,
  EventErrorEnvelope,
  EventPromptEnvelope,
  EventResolvedEnvelope,
  EventResponseCommand,
  OutboundEventEnvelope,
} from './types.js';

export const eventChoiceSchema = z.object({
  choiceId: z.string().min(1),
  text: z.string().min(1),
  energyCost: z.number().int().optional(),
  moneyCost: z.number().optional(),
  diamondCost: z.number().int().optional(),
});

export const eventEffectsSchema = z.object({
  stats: z.record(z.string(), z.number()).optional(),
  resources: z.object({
    energy: z.number().optional(),
    money: z.number().optional(),
    diamonds: z.number().optional(),
  }).optional(),
  relationships: z.array(
    z.object({
      personId: z.string().min(1),
      affinityDelta: z.number(),
    })
  ).optional(),
});

export const eventPromptEnvelopeSchema = z.object({
  type: z.literal('event_prompt'),
  eventId: z.string().min(1),
  instanceId: z.string().min(1),
  prompt: z.string().min(1),
  choices: z.array(eventChoiceSchema).min(1),
  metadata: z.record(z.string(), z.unknown()).optional(),
});

export const resolvedRelationshipEffectSchema = z.object({
  personId: z.string().min(1),
  name: z.string().min(1),
  affinityDelta: z.number(),
});

export const eventResolvedEnvelopeSchema = z.object({
  type: z.literal('event_resolved'),
  eventId: z.string().min(1),
  instanceId: z.string().min(1),
  resolutionText: z.string().min(1),
  effects: eventEffectsSchema.optional(),
  resolvedRelationships: z.array(resolvedRelationshipEffectSchema).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
});

export const eventErrorEnvelopeSchema = z.object({
  type: z.literal('event_error'),
  code: z.string().min(1),
  message: z.string().min(1),
  eventId: z.string().min(1).optional(),
  instanceId: z.string().min(1).optional(),
  details: z.record(z.string(), z.unknown()).optional(),
});

export const outboundEventEnvelopeSchema = z.discriminatedUnion('type', [
  eventPromptEnvelopeSchema,
  eventResolvedEnvelopeSchema,
  eventErrorEnvelopeSchema,
]);

export const eventResponseMessageSchema = z.object({
  eventId: z.string().min(1),
  choiceId: z.string().min(1),
});

export const eventResponseCommandSchema = z.object({
  type: z.literal('eventResponse'),
  message: eventResponseMessageSchema,
});

export function parseEventChoice(input: unknown): EventChoice {
  return eventChoiceSchema.parse(input);
}

export function parseEventEnvelope(input: unknown): OutboundEventEnvelope {
  return outboundEventEnvelopeSchema.parse(input) as OutboundEventEnvelope;
}

export function parseEventResponseCommand(input: unknown): EventResponseCommand {
  return eventResponseCommandSchema.parse(input);
}

export function parseEventPromptEnvelope(input: unknown): EventPromptEnvelope {
  return eventPromptEnvelopeSchema.parse(input);
}

export function parseEventResolvedEnvelope(input: unknown): EventResolvedEnvelope {
  return eventResolvedEnvelopeSchema.parse(input);
}

export function parseEventErrorEnvelope(input: unknown): EventErrorEnvelope {
  return eventErrorEnvelopeSchema.parse(input);
}
