/**
 * Support-case domain events — discriminated union.
 *
 * Pure module: no imports from @/server/db, do-client, outbox-producer, payments, fetch.
 */

export type TicketState =
  | 'open'
  | 'ai_handling'
  | 'awaiting_user'
  | 'escalated'
  | 'awaiting_agent'
  | 'human_handling'
  | 'resolved'
  | 'closed'
  | 'reopened';

export type CaseStatus =
  | 'opened'
  | 'vendor_review'
  | 'vendor_offered'
  | 'escalated'
  | 'ai_handling'
  | 'awaiting_info'
  | 'human_review'
  | 'resolved'
  | 'closed'
  | 'reopened';

export type CaseCategory =
  | 'quality_issue'
  | 'item_not_as_described'
  | 'no_show_vendor'
  | 'cannot_redeem'
  | 'cancellation_request'
  | 'fraud'
  | 'safety'
  | 'other';

export interface CaseTransitionContext {
  category?: CaseCategory;
  escapeUsed?: boolean;
  autoExecuted?: boolean;
}

export interface TicketTransitionContext {
  actorType: 'customer' | 'vendor' | 'ai' | 'human_agent' | 'system';
  reopenCount?: number;
  reopenLimit?: number;
}

export type SupportActorType = 'customer' | 'vendor' | 'human_agent' | 'system' | 'ai';

export type SupportCaseEvent =
  | {
      kind: 'case_transition_requested';
      caseId: string;
      to: CaseStatus;
      actorType: SupportActorType;
      actorId: string | null;
      reason?: string;
      at?: Date;
      ctx?: CaseTransitionContext;
      metadata?: Record<string, unknown>;
    }
  | {
      kind: 'case_message_posted';
      caseId: string;
    }
  | {
      kind: 'resolution_requested';
      caseId: string;
      purchaseId: string;
      outcome: string;
      amountCents: number | null;
      executedBy: 'vendor_auto' | 'customer_accept' | 'ai_auto' | 'human';
      email?: {
        templateKey: 'support.case_resolved' | 'support.customer_decided';
        recipients: Array<'customer' | 'vendor'>;
        params: Record<string, string>;
      };
    }
  | {
      kind: 'ticket_transition_requested';
      ticketId: string;
      to: TicketState;
      actorType: TicketTransitionContext['actorType'];
      actorId: string | null;
      reason?: string;
      at?: Date;
      reopenCount?: number;
      reopenLimit?: number;
      metadata?: Record<string, unknown>;
    };
