/**
 * Platform Event Catalog
 *
 * Typed event definitions for the EventBus. Each event has a dot-separated name
 * and a strongly-typed payload. Services publish events; listeners subscribe.
 *
 * Naming convention: <module>.<entity>.<action>
 *   e.g. shift.signup.created, campaign.email.sent, payment.donation.completed
 */

// =============================================================================
// SHIFT EVENTS
// =============================================================================

export interface ShiftCreatedEvent {
  shiftId: string;
  title: string;
  date: string;
  startTime: string;
  endTime: string;
  cutId?: string | null;
  cutName?: string | null;
  createdByUserId: string;
}

export interface ShiftUpdatedEvent {
  shiftId: string;
  title: string;
  date: string;
  startTime: string;
  endTime: string;
  cutId?: string | null;
  cutName?: string | null;
  changes: string[]; // field names that changed
}

export interface ShiftDeletedEvent {
  shiftId: string;
  title: string;
  date: string;
}

export interface ShiftSignupCreatedEvent {
  shiftId: string;
  shiftTitle: string;
  shiftDate: string;
  userName: string;
  userEmail: string;
  userId?: string | null;
  cutName?: string | null;
  signupType: 'admin' | 'volunteer' | 'public';
}

export interface ShiftSignupCancelledEvent {
  shiftId: string;
  shiftTitle: string;
  shiftDate: string;
  userName: string;
  userEmail: string;
  signupType: 'admin' | 'volunteer' | 'public';
}

// =============================================================================
// CAMPAIGN EVENTS (Influence)
// =============================================================================

export interface CampaignCreatedEvent {
  campaignId: string;
  title: string;
  slug: string;
  createdByUserId: string;
}

export interface CampaignUpdatedEvent {
  campaignId: string;
  title: string;
  slug: string;
  changes: string[];
}

export interface CampaignDeletedEvent {
  campaignId: string;
  title: string;
  slug: string;
}

export interface CampaignPublishedEvent {
  campaignId: string;
  title: string;
  slug: string;
}

export interface CampaignStatusChangedEvent {
  campaignId: string;
  title: string;
  slug: string;
  oldStatus: string;
  newStatus: string;
}

export interface CampaignEmailSentEvent {
  email: string;
  name: string;
  campaignSlug: string;
  postalCode?: string;
}

// =============================================================================
// RESPONSE EVENTS (Influence)
// =============================================================================

export interface ResponseSubmittedEvent {
  responseId: string;
  campaignId: string;
  campaignTitle: string;
  representativeName: string;
  userEmail?: string;
}

export interface ResponseApprovedEvent {
  responseId: string;
  campaignId: string;
  campaignTitle: string;
}

export interface ResponseRejectedEvent {
  responseId: string;
  campaignId: string;
  campaignTitle: string;
  reason?: string;
}

// =============================================================================
// CANVASS EVENTS
// =============================================================================

export interface CanvassSessionStartedEvent {
  sessionId: string;
  userId: string;
  userName: string;
  cutId: string;
  cutName: string;
}

export interface CanvassSessionCompletedEvent {
  sessionId: string;
  userId: string;
  userName: string;
  userEmail: string;
  cutName: string;
  visitCount: number;
  outcomes: Record<string, number>;
}

export interface CanvassVisitRecordedEvent {
  visitId: string;
  sessionId: string;
  addressId: string;
  outcome: string;
  email?: string | null;
  name?: string | null;
  supportLevel?: string | null;
  sign?: boolean;
  address?: string | null;
}

// =============================================================================
// USER EVENTS
// =============================================================================

export interface UserCreatedEvent {
  userId: string;
  email: string;
  name: string;
  role: string;
}

export interface UserUpdatedEvent {
  userId: string;
  email: string;
  name: string;
  role: string;
  changes: string[];
}

export interface UserApprovedEvent {
  userId: string;
  email: string;
  name: string;
  role: string;
  approvedByUserId: string;
}

export interface UserDeletedEvent {
  userId: string;
  email: string;
  name: string;
}

// =============================================================================
// PAYMENT EVENTS
// =============================================================================

export interface SubscriptionActivatedEvent {
  email: string;
  name: string;
  planName: string;
  subscriptionId: string;
  amountCents?: number;
}

export interface SubscriptionCancelledEvent {
  email: string;
  name: string;
  subscriptionId: string;
}

export interface DonationCompletedEvent {
  email: string;
  name: string;
  amountCents: number;
  orderId: string;
  donationPageSlug?: string;
}

export interface DonationRefundedEvent {
  email: string;
  orderId: string;
  amountCents: number;
}

export interface ProductPurchasedEvent {
  email: string;
  name: string;
  productTitle: string;
  amountCents: number;
  orderId: string;
}

// =============================================================================
// SMS EVENTS
// =============================================================================

export interface SmsCampaignStartedEvent {
  campaignId: string;
  title: string;
  recipientCount: number;
}

export interface SmsCampaignCompletedEvent {
  campaignId: string;
  title: string;
  sentCount: number;
  failedCount: number;
}

export interface SmsMessageSentEvent {
  messageId: string;
  campaignId?: string;
  phone: string;
  body: string;
}

export interface SmsMessageReceivedEvent {
  messageId: string;
  conversationId: string;
  phone: string;
  body: string;
  responseType?: string; // POSITIVE, NEGATIVE, QUESTION, OPT_OUT, NEUTRAL
}

// =============================================================================
// MEDIA EVENTS
// =============================================================================

export interface VideoPublishedEvent {
  videoId: string;
  title: string;
  publishedByUserId: string;
}

export interface VideoUnpublishedEvent {
  videoId: string;
  title: string;
}

export interface VideoViewedEvent {
  videoId: string;
  videoTitle: string;
  userId?: string | null;
  sessionId: string;
}

// =============================================================================
// TICKETED EVENT EVENTS
// =============================================================================

export interface TicketedEventPublishedEvent {
  eventId: string;
  title: string;
  date: string;
  startTime: string;
  endTime?: string;
  location?: string;
  gancioEventId?: number | null;
}

export interface TicketedEventCancelledEvent {
  eventId: string;
  title: string;
}

// =============================================================================
// MEETING EVENTS
// =============================================================================

export interface MeetingCreatedEvent {
  meetingId: string;
  title: string;
  scheduledAt: string;
  jitsiRoomName?: string;
  createdByUserId: string;
}

export interface MeetingUpdatedEvent {
  meetingId: string;
  title: string;
  scheduledAt: string;
  changes: string[];
}

export interface MeetingDeletedEvent {
  meetingId: string;
  title: string;
}

// =============================================================================
// SOCIAL EVENTS
// =============================================================================

export interface ImpactStoryPublishedEvent {
  storyId: string;
  title: string;
  authorUserId: string;
  campaignId?: string | null;
}

// =============================================================================
// CONTACT / CRM EVENTS
// =============================================================================

export interface ContactTagsChangedEvent {
  email: string;
  name: string;
  contactId: string;
  addedTags: string[];
  removedTags: string[];
}

export interface ContactCreatedEvent {
  contactId: string;
  email?: string;
  name: string;
}

export interface ContactMergedEvent {
  survivorId: string;
  mergedId: string;
  survivorEmail?: string;
}

export interface AddressUpdatedEvent {
  email: string;
  name: string;
  supportLevel?: string | null;
  sign?: boolean;
  address?: string | null;
}

// =============================================================================
// REENGAGEMENT EVENTS
// =============================================================================

export interface ReengagementSentEvent {
  email: string;
  name: string;
}

// =============================================================================
// LISTMONK WEBHOOK EVENTS (inbound from Listmonk)
// =============================================================================

export interface ListmonkEmailOpenedEvent {
  subscriberEmail: string;
  campaignId: number;
  campaignName: string;
}

export interface ListmonkEmailClickedEvent {
  subscriberEmail: string;
  campaignId: number;
  campaignName: string;
  url: string;
}

export interface ListmonkEmailBouncedEvent {
  subscriberEmail: string;
  campaignId: number;
  bounceType: string;
}

export interface ListmonkUnsubscribedEvent {
  subscriberEmail: string;
  listId: number;
  listName: string;
}

// =============================================================================
// EVENT MAP — maps event names to payload types
// =============================================================================

export interface PlatformEventMap {
  // Shifts
  'shift.created': ShiftCreatedEvent;
  'shift.updated': ShiftUpdatedEvent;
  'shift.deleted': ShiftDeletedEvent;
  'shift.signup.created': ShiftSignupCreatedEvent;
  'shift.signup.cancelled': ShiftSignupCancelledEvent;

  // Campaigns
  'campaign.created': CampaignCreatedEvent;
  'campaign.updated': CampaignUpdatedEvent;
  'campaign.deleted': CampaignDeletedEvent;
  'campaign.published': CampaignPublishedEvent;
  'campaign.status.changed': CampaignStatusChangedEvent;
  'campaign.email.sent': CampaignEmailSentEvent;

  // Responses
  'response.submitted': ResponseSubmittedEvent;
  'response.approved': ResponseApprovedEvent;
  'response.rejected': ResponseRejectedEvent;

  // Canvass
  'canvass.session.started': CanvassSessionStartedEvent;
  'canvass.session.completed': CanvassSessionCompletedEvent;
  'canvass.visit.recorded': CanvassVisitRecordedEvent;

  // Users
  'user.created': UserCreatedEvent;
  'user.updated': UserUpdatedEvent;
  'user.approved': UserApprovedEvent;
  'user.deleted': UserDeletedEvent;

  // Payments
  'payment.subscription.activated': SubscriptionActivatedEvent;
  'payment.subscription.cancelled': SubscriptionCancelledEvent;
  'payment.donation.completed': DonationCompletedEvent;
  'payment.donation.refunded': DonationRefundedEvent;
  'payment.product.purchased': ProductPurchasedEvent;

  // SMS
  'sms.campaign.started': SmsCampaignStartedEvent;
  'sms.campaign.completed': SmsCampaignCompletedEvent;
  'sms.message.sent': SmsMessageSentEvent;
  'sms.message.received': SmsMessageReceivedEvent;

  // Media
  'media.video.published': VideoPublishedEvent;
  'media.video.unpublished': VideoUnpublishedEvent;
  'media.video.viewed': VideoViewedEvent;

  // Ticketed Events
  'ticketed-event.published': TicketedEventPublishedEvent;
  'ticketed-event.cancelled': TicketedEventCancelledEvent;

  // Meetings
  'meeting.created': MeetingCreatedEvent;
  'meeting.updated': MeetingUpdatedEvent;
  'meeting.deleted': MeetingDeletedEvent;

  // Social
  'social.impact-story.published': ImpactStoryPublishedEvent;

  // Contact / CRM
  'contact.created': ContactCreatedEvent;
  'contact.merged': ContactMergedEvent;
  'contact.tags.changed': ContactTagsChangedEvent;
  'contact.address.updated': AddressUpdatedEvent;

  // Reengagement
  'reengagement.sent': ReengagementSentEvent;

  // Listmonk webhooks (inbound)
  'listmonk.email.opened': ListmonkEmailOpenedEvent;
  'listmonk.email.clicked': ListmonkEmailClickedEvent;
  'listmonk.email.bounced': ListmonkEmailBouncedEvent;
  'listmonk.unsubscribed': ListmonkUnsubscribedEvent;
}

/** All valid platform event names */
export type PlatformEventName = keyof PlatformEventMap;

/** Helper: extract payload type for a given event name */
export type EventPayload<E extends PlatformEventName> = PlatformEventMap[E];
