import type { WebhookTriggerEvents } from "@calcom/prisma/enums";
import type { WebhookSubscriber } from "../dto/types";
import type { WebhookPayload } from "../factory/types";
import type {
  BookingCancelledParams,
  BookingCreatedParams,
  BookingNoShowParams,
  BookingPaidParams,
  BookingPaymentInitiatedParams,
  BookingRejectedParams,
  BookingRequestedParams,
  BookingRescheduledParams,
  CancelScheduledMeetingWebhooksParams,
  ScheduleMeetingWebhooksParams,
  ScheduleNoShowWebhooksParams,
} from "../types/params";

export interface GetSubscribersOptions {
  userId?: number | null;
  eventTypeId?: number | null;
  triggerEvent: WebhookTriggerEvents;
  teamId?: number | number[] | null;
  orgId?: number | null;
  oAuthClientId?: string | null;
}

// Repository Interface - Data access operations
export interface IWebhookRepository {
  getSubscribers(options: GetSubscribersOptions): Promise<WebhookSubscriber[]>;
}

// Processing Interface - Webhook processing operations
export interface IWebhookProcessor {
  processWebhooks(
    trigger: WebhookTriggerEvents,
    payload: WebhookPayload,
    subscribers: WebhookSubscriber[]
  ): Promise<void>;
}

// Scheduling Interface - Webhook scheduling operations
export interface IWebhookScheduler {
  scheduleTimeBasedWebhook(
    trigger: WebhookTriggerEvents,
    scheduledAt: Date,
    bookingData: Record<string, unknown>,
    subscriber: WebhookSubscriber,
    evt: Record<string, unknown>,
    isDryRun?: boolean
  ): Promise<void>;
  cancelScheduledWebhooks(
    bookingId: number,
    triggers: WebhookTriggerEvents[],
    isDryRun?: boolean
  ): Promise<void>;
  scheduleDelayedWebhooks(
    trigger: WebhookTriggerEvents,
    payload: WebhookPayload,
    scheduledAt: Date,
    options?: { teamId?: number | number[] | null; orgId?: number | null },
    subscribers?: WebhookSubscriber[],
    isDryRun?: boolean
  ): Promise<void>;
}

// Combined interface for backward compatibility (can be removed later)
export interface IWebhookService extends IWebhookRepository, IWebhookProcessor, IWebhookScheduler {}

// Event Emission Interface - Direct parameter-based methods
export interface IBookingEventEmitter {
  emitBookingPaymentInitiated(params: BookingPaymentInitiatedParams): Promise<void>;
  emitBookingCreated(params: BookingCreatedParams): Promise<void>;
  emitBookingCancelled(params: BookingCancelledParams): Promise<void>;
  emitBookingRequested(params: BookingRequestedParams): Promise<void>;
  emitBookingRescheduled(params: BookingRescheduledParams): Promise<void>;
  emitBookingPaid(params: BookingPaidParams): Promise<void>;
  emitBookingNoShow(params: BookingNoShowParams): Promise<void>;
  emitBookingRejected(params: BookingRejectedParams): Promise<void>;
}

// Scheduling Interface - Webhook scheduling operations
export interface IBookingScheduler {
  scheduleMeetingWebhooks(params: ScheduleMeetingWebhooksParams): Promise<void>;
  cancelScheduledMeetingWebhooks(params: CancelScheduledMeetingWebhooksParams): Promise<void>;
  scheduleNoShowWebhooks(params: ScheduleNoShowWebhooksParams): Promise<void>;
}

// Combined interface for backward compatibility (can be removed later)
export interface IBookingWebhookService extends IBookingEventEmitter, IBookingScheduler {}

export interface IRecordingWebhookService {
  emitRecordingReady(params: {
    evt: import("@calcom/types/Calendar").CalendarEvent;
    downloadLink: string;
    booking?: {
      id: number;
      eventTypeId?: number | null;
      userId?: number | null;
    };
    teamId?: number | null;
    orgId?: number | null;
    platformClientId?: string;
    isDryRun?: boolean;
  }): Promise<void>;

  emitTranscriptionGenerated(params: {
    evt: import("@calcom/types/Calendar").CalendarEvent;
    downloadLinks?: {
      transcription?: Array<{
        format: string;
        link: string;
      }>;
      recording?: string;
    };
    booking?: {
      id: number;
      eventTypeId?: number | null;
      userId?: number | null;
    };
    teamId?: number | null;
    orgId?: number | null;
    platformClientId?: string;
    isDryRun?: boolean;
  }): Promise<void>;
}

// OOO Webhook Service Interface - Out-of-Office webhook operations
export interface IOOOWebhookService {
  emitOOOCreated(params: {
    oooEntry: {
      id: number;
      start: string;
      end: string;
      createdAt: string;
      updatedAt: string;
      notes: string | null;
      reason: {
        emoji?: string;
        reason?: string;
      };
      reasonId: number;
      user: {
        id: number;
        name: string | null;
        username: string | null;
        timeZone: string;
        email: string;
      };
      toUser: {
        id: number;
        name?: string | null;
        username?: string | null;
        email?: string;
        timeZone?: string;
      } | null;
      uuid: string;
    };
    userId?: number | null;
    teamId?: number | null;
    orgId?: number | null;
    platformClientId?: string;
    isDryRun?: boolean;
  }): Promise<void>;
}
