import {
  createGetDB,
  type Generated,
  type Timestamp,
  type NamespaceDB,
  type NamespaceInsertable,
  type NamespaceSelectable,
  type NamespaceTable,
  type NamespaceTableName,
  type NamespaceTransaction,
  type NamespaceUpdateable,
} from "@tailor-platform/sdk/kysely";

export interface Namespace {
  "main-db": {
    ChannelRoutingBinding: {
      id: Generated<string>;
      targetType: string;
      targetId: string;
      channelId: "IN_APP" | "EMAIL" | "SMS" | "PUSH" | "SLACK" | "TEAMS";
      externalChannelRef: string;
      displayLabel: string | null;
      isActive: boolean;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    DestinationDeliveryLog: {
      id: Generated<string>;
      eventType: string;
      sourceType: string;
      sourceId: string;
      targetType: string;
      targetId: string;
      channelId: string;
      externalChannelRef: string;
      idempotencyKey: string;
      subject: string;
      body: string;
      status: "PENDING" | "SENT" | "FAILED";
      providerMessageId: string | null;
      providerResponse: string | null;
      failureReason: string | null;
      retryCount: number;
      attemptedAt: Timestamp;
      completedAt: Timestamp | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    EventCategoryBinding: {
      id: Generated<string>;
      eventType: string;
      categoryId: string;
      transactional: boolean;
      defaultChannels: string[];
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    Notification: {
      id: Generated<string>;
      recipientUserId: string;
      channelId: string;
      eventType: string;
      sourceType: string;
      sourceId: string;
      reason: "SUBSCRIBED" | "ASSIGNED" | "AUTHOR" | "MENTION";
      locale: string;
      payloadVars: string | null;
      subject: string;
      body: string;
      htmlBody: string | null;
      idempotencyKey: string;
      deliveryStatus: "QUEUED" | "SENT" | "DELIVERED" | "FAILED" | "BOUNCED";
      engagementStatuses: string[];
      seenAt: Timestamp | null;
      readAt: Timestamp | null;
      archivedAt: Timestamp | null;
      adapterMessageId: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    NotificationCategory: {
      id: Generated<string>;
      categoryId: string;
      displayName: string;
      optOutAllowed: boolean;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    NotificationChannel: {
      id: Generated<string>;
      channelId: "IN_APP" | "EMAIL" | "SMS" | "PUSH" | "SLACK" | "TEAMS";
      kind: "PERSONAL" | "DESTINATION";
      displayName: string;
      capabilities: {
        supportsHtmlBody: boolean;
        supportsAttachments: boolean;
        supportsRichActions: boolean;
      };
      enabled: boolean;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    NotificationDeliveryAudit: {
      id: Generated<string>;
      notificationId: string;
      eventType: "QUEUED" | "SENT" | "DELIVERED" | "SEEN" | "READ" | "ARCHIVED" | "FAILED" | "BOUNCED" | "OPENED";
      occurredAt: Timestamp;
      occurredBy: string | null;
      errorClass: string | null;
      errorDetail: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    NotificationEvent: {
      id: Generated<string>;
      eventType: string;
      sourceType: string;
      sourceId: string;
      actorUserId: string | null;
      payload: string;
      payloadHash: string;
      status: "PENDING" | "DISPATCHED" | "NO_DELIVERY";
      dispatchedAt: Timestamp | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    NotificationPreference: {
      id: Generated<string>;
      userId: string;
      categoryId: string;
      channelId: string;
      allowed: boolean;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    NotificationSubscription: {
      id: Generated<string>;
      userId: string;
      sourceType: string;
      sourceId: string;
      subscribedAt: Timestamp;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    NotificationTemplate: {
      id: Generated<string>;
      eventType: string;
      channelId: string;
      locale: string;
      subject: string;
      body: string;
      htmlBody: string | null;
      variableSchema: string;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SlackWorkspaceIntegration: {
      id: Generated<string>;
      teamId: string;
      teamName: string | null;
      botUserId: string | null;
      status: "REVOKED" | "ACTIVE";
      installedAt: Timestamp;
      lastValidatedAt: Timestamp | null;
      revokedAt: Timestamp | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }
  }
}

export const getDB = createGetDB<Namespace>();

export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;

export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =
  NamespaceTransaction<Namespace, K>;

type TableName = NamespaceTableName<Namespace>;
export type Table<T extends TableName> = NamespaceTable<Namespace, T>;

export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;
export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;
export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;
