/**
 * Site Infrastructure Contracts
 *
 * These types group the operational contracts that sit around site plumbing:
 * webhooks, API keys, backup/restore flows, and related presigned upload/import steps.
 *
 * Note: Do NOT use these API types as validation schemas. They document the wire
 * request/response shapes; service-layer validation still belongs with the route/use-case
 * flow that owns each operation.
 */
import type { UploadIntentContract } from "./media";
export type WebhookEndpointRecord = {
    id: string;
    name: string;
    url: string;
    events: string[];
    enabled: boolean;
    hasSecret: boolean;
    createdAt: string;
    updatedAt: string;
    siteId: string;
    failureCount: number;
    lastFailureAt: string | null;
    lastSuccessAt: string | null;
    lastTriggeredAt: string | null;
};
export type WebhookDeliveryLogRecord = {
    id: string;
    endpointId: string;
    siteId: string;
    event: string;
    payload: unknown;
    statusCode: number | null;
    responseBody: string | null;
    responseTimeMs: number | null;
    errorMessage: string | null;
    deliveredAt: string;
};
export type ListWebhooksResponse = {
    endpoints: WebhookEndpointRecord[];
    supportedEvents: readonly string[];
};
export type CreateWebhookRequest = {
    name?: string;
    url: string;
    events: string[];
};
export type CreateWebhookResponse = {
    endpoint: WebhookEndpointRecord;
    secret: string;
    message: string;
};
export type GetWebhookResponse = {
    endpoint: WebhookEndpointRecord;
    recentDeliveries: WebhookDeliveryLogRecord[];
};
export type UpdateWebhookRequest = {
    name?: string;
    url?: string;
    events?: string[];
    enabled?: boolean;
    regenerateSecret?: boolean;
};
export type UpdateWebhookResponse = {
    endpoint: WebhookEndpointRecord;
    newSecret?: string;
    message?: string;
};
export type DeleteWebhookResponse = {
    success: boolean;
};
export type ApiKeyType = "content" | "preview" | "management";
export type ApiKeyRecord = {
    id: string;
    name: string;
    keyPrefix: string;
    keyHint: string | null;
    keyType: ApiKeyType;
    createdAt: string;
    lastUsedAt: string | null;
    revokedAt: string | null;
    site?: {
        id: string;
        title: string;
        slug: string;
    };
};
export type PreviewKeyRecord = {
    id: string;
    name: string;
    keyPrefix: string;
    keyHint: string | null;
    createdAt: string;
    lastUsedAt: string | null;
};
export type ApiKeyAccessLogRecord = {
    id: string;
    keyId: string;
    keyType: ApiKeyType;
    accessedAt: string;
    ipAddress: string | null;
    userAgent: string | null;
    path: string | null;
};
export type ListSiteApiKeysResponse = {
    contentKeys: ApiKeyRecord[];
    previewKey: PreviewKeyRecord | null;
    managementKeys: ApiKeyRecord[];
};
export type CreateSiteApiKeyRequest = {
    name: string;
    environment?: "live" | "test";
};
export type CreateSiteApiKeyResponse = {
    key: string;
    keyId: string;
    message: string;
};
export type RevokeSiteApiKeyResponse = {
    message: string;
};
export type GetSitePreviewKeyResponse = {
    previewKey: PreviewKeyRecord | null;
};
export type CreateSitePreviewKeyResponse = {
    key: string;
    keyId: string;
    message: string;
};
export type ManagementKeyRecord = {
    id: string;
    name: string | null;
    keyPrefix: string;
    keyHint: string | null;
    createdAt: string;
    lastUsedAt: string | null;
};
export type ListManagementKeysResponse = {
    managementKeys: ManagementKeyRecord[];
};
export type CreateManagementKeyRequest = {
    name?: string;
};
export type CreateManagementKeyResponse = {
    key: string;
    keyId: string;
    message: string;
};
export type RevokeManagementKeyRequest = {
    keyId: string;
};
export type RevokeManagementKeyResponse = {
    message: string;
};
export type ApiKeyAccessLogsPagination = {
    limit: number;
    offset: number;
    hasMore: boolean;
};
export type GetSiteApiKeyAccessLogsResponse = {
    logs: ApiKeyAccessLogRecord[];
    pagination: ApiKeyAccessLogsPagination;
};
export type BackupAccessImportResult = {
    memberships: {
        invited: number;
        skipped: number;
        emailsSent: number;
        emailsFailed: number;
        details: Array<{
            email: string;
            action: string;
            role: string;
            reason?: string;
        }>;
    };
    apiKeys: {
        created: number;
        keys: Array<{
            name: string;
            keyPrefix: string;
            keyId: string;
            fullKey: string;
        }>;
    };
};
export type BackupImportResponse = {
    ok: boolean;
    siteId?: string;
    dryRun?: boolean;
    counts?: Record<string, {
        created: number;
        updated: number;
        failed: number;
    }>;
    warnings?: string[];
    errors?: Array<{
        table: string;
        id: string;
        error: string;
    }>;
    access?: BackupAccessImportResult;
    error?: string;
    code?: string;
    details?: unknown;
};
export type BackupPreviewResponse = {
    ok: boolean;
    manifest?: {
        siteId: string;
        siteSlug: string;
        siteTitle: string;
        exportedAt: string;
        tableCount: number;
        totalRecords: number;
        pageCount: number;
        blockCount: number;
        contentEntryCount: number;
        formCount: number;
        navigationMenuCount: number;
        mediaCount: number;
        mediaBytes: number;
    };
    storagePath?: string;
    error?: string;
    code?: string;
};
export type CreateBackupUploadUrlRequest = {
    filename: string;
};
export type CreateBackupUploadUrlResponse = {
    signedUrl: string;
    token: string;
    storagePath: string;
};
export type CreateMediaUploadUrlRequest = {
    siteId: string;
    filename: string;
    bytes: number;
    mimeType?: string;
    uploadIntent?: UploadIntentContract;
};
export type CreateMediaUploadUrlResponse = {
    signedUrl: string;
    storagePath: string;
    bucket: string;
    bytes: number;
    uploadSessionId: string;
};
export type MediaUploadFinalizeRequest = {
    siteId: string;
    filename: string;
    uploadSessionId: string;
    labelHints?: string[];
    isThumbnail?: boolean;
    identifier?: string;
};
export type CreateInstagramZipUploadUrlRequest = {
    siteId: string;
    filename: string;
    bytes: number;
};
export type CreateInstagramZipUploadUrlResponse = {
    signedUrl: string;
    storagePath: string;
};
export type InstagramUploadZipRequest = {
    siteId: string;
    storagePath: string;
    bucket?: string;
};
export type CreateSiteLogoUploadUrlRequest = {
    siteId: string;
    filename: string;
    bytes: number;
    mimeType?: string;
};
export type CreateSiteLogoUploadUrlResponse = {
    signedUrl: string;
    storagePath: string;
};
export type UploadSiteLogoRequest = {
    siteId: string;
    storagePath: string;
    palette?: string[];
};
export type CreateNewsletterSubscribersImportUploadUrlRequest = {
    filename: string;
    bytes: number;
};
export type CreateNewsletterSubscribersImportUploadUrlResponse = {
    signedUrl: string;
    storagePath: string;
};
export type ImportNewsletterSubscribersCsvRequest = {
    storagePath: string;
    listIds?: string[];
};
export type DeleteBackupUploadRequest = {
    storagePath: string;
};
export type DeleteBackupUploadResponse = {
    deleted: boolean;
};
export type BackupPreviewRequest = {
    storagePath: string;
};
export type ImportSiteBackupRequest = {
    storagePath: string;
    clean?: boolean;
    dryRun?: boolean;
    membershipMode?: "skip" | "invite" | "preview";
    apiKeyMode?: "skip" | "regenerate" | "preview";
    sendInvitationEmails?: boolean;
};
export type ImportBackupAsNewSiteRequest = {
    storagePath: string;
    title?: string;
};
export type ImportBackupAsNewSiteResponse = {
    ok: boolean;
    siteId?: string;
    slug?: string;
    title?: string;
    counts?: Record<string, {
        created: number;
        updated: number;
        failed: number;
    }>;
    warnings?: string[];
    errors?: Array<{
        table: string;
        id: string;
        error: string;
    }>;
    error?: string;
    code?: string;
};
