import { writeGeneratedFile } from "../../helpers/fs";
import logger from "../../helpers/logger";
import { generateFileHeader } from "./fileHeader";

const FILE_NAME = "webhook.ts";

export function generateWebhookTypes(outputDir: string): void {
  logger.debug(`Generating webhook types file: ${FILE_NAME}`);

  const content = `${generateFileHeader(FILE_NAME)}
import { Actor } from './systemDataTypes';

export type AttioWebhookStatus =
  | "active"
  | "degraded"
  | "inactive";

export type AttioWebhookEventType =
  | "comment.created"
  | "comment.resolved"
  | "comment.unresolved"
  | "comment.deleted"
  | "list.created"
  | "list.updated"
  | "list.deleted"
  | "list-attribute.created"
  | "list-attribute.updated"
  | "list-entry.created"
  | "list-entry.updated"
  | "list-entry.deleted"
  | "object-attribute.created"
  | "object-attribute.updated"
  | "note.created"
  | "note-content.updated"
  | "note.updated"
  | "note.deleted"
  | "record.created"
  | "record.merged"
  | "record.updated"
  | "record.deleted"
  | "task.created"
  | "task.updated"
  | "task.deleted"
  | "workspace-member.created";

export interface AttioWebhookSubscription {
  event_type: AttioWebhookEventType;
  filter?: Record<string, any>;
}

export interface AttioWebhook {
  id: {
    workspace_id: string;
    webhook_id: string;
  };
  target_url: string;
  status: AttioWebhookStatus;
  subscriptions: AttioWebhookSubscription[];
  created_at: string;
}

export interface WebhookQueryParams {
  limit?: number;
  offset?: number;
}

export type CreateWebhookInput = Pick<AttioWebhook, 'target_url' | 'subscriptions'>;

// Helpers for common properties in webhook events
type WithActor = { actor: Actor };
type WithParent = { parent_object_id: string; parent_record_id: string };

type WebhookIds = {
  Record: { workspace_id: string; object_id: string; record_id: string };
  RecordWithAttr: { workspace_id: string; object_id: string; record_id: string; attribute_id: string };
  ListEntry: { workspace_id: string; list_id: string; entry_id: string };
  ListAttr: { workspace_id: string; list_id: string; attribute_id: string };
  List: { workspace_id: string; list_id: string };
  Note: { workspace_id: string; note_id: string };
  Task: { workspace_id: string; task_id: string };
  Comment: { workspace_id: string; comment_id: string };
  WorkspaceMember: { workspace_id: string; workspace_member_id: string };
  ObjectAttr: { workspace_id: string; object_id: string; attribute_id: string };
};

// Discriminated union for webhook event data
export type WebhookEventData =
  // Record events
  | ({ event_type: "record.created"; id: WebhookIds["Record"] } & WithActor)
  | ({ event_type: "record.updated"; id: WebhookIds["RecordWithAttr"] } & WithActor)
  | ({ event_type: "record.deleted"; id: WebhookIds["Record"] } & WithActor)
  | ({ event_type: "record.merged"; id: WebhookIds["Record"]; duplicate_object_id: string; duplicate_record_id: string } & WithActor)

  // Object attribute events
  | ({ event_type: "object-attribute.created"; id: WebhookIds["ObjectAttr"] } & WithActor)
  | ({ event_type: "object-attribute.updated"; id: WebhookIds["ObjectAttr"] } & WithActor)

  // List entry events
  | ({ event_type: "list-entry.created"; id: WebhookIds["ListEntry"] } & WithActor & WithParent)
  | ({ event_type: "list-entry.updated"; id: WebhookIds["ListEntry"] } & WithActor & WithParent)
  | ({ event_type: "list-entry.deleted"; id: WebhookIds["ListEntry"] } & WithActor & WithParent)

  // List attribute events
  | ({ event_type: "list-attribute.created"; id: WebhookIds["ListAttr"] } & WithActor)
  | ({ event_type: "list-attribute.updated"; id: WebhookIds["ListAttr"] } & WithActor)

  // List events
  | ({ event_type: "list.created"; id: WebhookIds["List"] } & WithActor)
  | ({ event_type: "list.updated"; id: WebhookIds["List"] } & WithActor)
  | ({ event_type: "list.deleted"; id: WebhookIds["List"] } & WithActor)

  // Note events
  | ({ event_type: "note.created"; id: WebhookIds["Note"] } & WithActor & WithParent)
  | ({ event_type: "note.updated"; id: WebhookIds["Note"] } & WithActor & WithParent)
  | ({ event_type: "note.deleted"; id: WebhookIds["Note"] } & WithParent)

  // Note content events
  | ({ event_type: "note-content.updated"; id: WebhookIds["Note"] } & WithActor & WithParent)

  // Task events
  | ({ event_type: "task.created"; id: WebhookIds["Task"] } & WithActor)
  | ({ event_type: "task.updated"; id: WebhookIds["Task"] } & WithActor)
  | ({ event_type: "task.deleted"; id: WebhookIds["Task"] } & WithActor)

  // Comment events
  | ({ event_type: "comment.created"; id: WebhookIds["Comment"]; thread_id: string; object_id: string; record_id: string; list_id: string; entry_id: string } & WithActor)
  | ({ event_type: "comment.resolved"; id: WebhookIds["Comment"] } & WithActor)
  | ({ event_type: "comment.unresolved"; id: WebhookIds["Comment"] } & WithActor)
  | ({ event_type: "comment.deleted"; id: WebhookIds["Comment"] } & WithActor)

  // Workspace member events
  | ({ event_type: "workspace-member.created"; id: WebhookIds["WorkspaceMember"] } & WithActor);

export type WebhookEventDataByType<T extends AttioWebhookEventType> = Extract<WebhookEventData, { event_type: T }>;
`;

  writeGeneratedFile(outputDir, FILE_NAME, content);
}
