import type { PhotoManifestItem } from '@afilmory/builder'

export type PhotoSyncActionType = 'insert' | 'update' | 'delete' | 'conflict' | 'noop' | 'error'

export type PhotoSyncResolution = 'prefer-storage' | 'prefer-database' | undefined

export interface PhotoSyncSnapshot {
  size: number | null
  etag: string | null
  lastModified: string | null
  metadataHash: string | null
}

export interface PhotoSyncAction {
  type: PhotoSyncActionType
  storageKey: string
  photoId: string | null
  applied: boolean
  resolution?: PhotoSyncResolution
  reason?: string
  conflictId?: string | null
  conflictPayload?: PhotoSyncConflictPayload | null
  snapshots?: {
    before?: PhotoSyncSnapshot | null
    after?: PhotoSyncSnapshot | null
  }
  manifestBefore?: PhotoManifestItem | null
  manifestAfter?: PhotoManifestItem | null
}

export interface PhotoSyncResultSummary {
  storageObjects: number
  databaseRecords: number
  inserted: number
  updated: number
  deleted: number
  conflicts: number
  skipped: number
  errors: number
}

export interface PhotoSyncResult {
  summary: PhotoSyncResultSummary
  actions: PhotoSyncAction[]
}

export interface PhotoSyncRunRecord {
  id: string
  dryRun: boolean
  summary: PhotoSyncResultSummary
  actionsCount: number
  startedAt: string
  completedAt: string
}

export interface PhotoSyncStatus {
  lastRun: PhotoSyncRunRecord | null
}

export type PhotoSyncConflictType = 'missing-in-storage' | 'metadata-mismatch' | 'photo-id-conflict'

export interface PhotoSyncConflictPayload {
  type: PhotoSyncConflictType
  storageSnapshot?: PhotoSyncSnapshot | null
  recordSnapshot?: PhotoSyncSnapshot | null
  incomingStorageKey?: string | null
}

export interface PhotoSyncConflict {
  id: string
  storageKey: string
  photoId: string | null
  reason: string | null
  payload: PhotoSyncConflictPayload | null
  manifestVersion: string
  manifest: PhotoAssetManifestPayload
  storageProvider: string
  syncedAt: string
  updatedAt: string
}

export interface RunPhotoSyncPayload {
  dryRun?: boolean
}

export type PhotoSyncProgressStage = 'missing-in-db' | 'orphan-in-db' | 'metadata-conflicts' | 'status-reconciliation'

export interface PhotoSyncStageTotals {
  'missing-in-db': number
  'orphan-in-db': number
  'metadata-conflicts': number
  'status-reconciliation': number
}

export type PhotoSyncLogLevel = 'info' | 'success' | 'warn' | 'error'

export interface PhotoSyncLogPayload {
  level: PhotoSyncLogLevel
  message: string
  timestamp: string
  stage?: PhotoSyncProgressStage | null
  storageKey?: string
  details?: Record<string, unknown> | null
}

export type PhotoSyncProgressEvent =
  | {
      type: 'start'
      payload: {
        summary: PhotoSyncResultSummary
        totals: PhotoSyncStageTotals
        options: { dryRun: boolean }
      }
    }
  | {
      type: 'stage'
      payload: {
        stage: PhotoSyncProgressStage
        status: 'start' | 'complete'
        processed: number
        total: number
        summary: PhotoSyncResultSummary
      }
    }
  | {
      type: 'action'
      payload: {
        stage: PhotoSyncProgressStage
        index: number
        total: number
        action: PhotoSyncAction
        summary: PhotoSyncResultSummary
      }
    }
  | {
      type: 'complete'
      payload: PhotoSyncResult
    }
  | {
      type: 'error'
      payload: {
        message: string
      }
    }
  | {
      type: 'log'
      payload: PhotoSyncLogPayload
    }

export type PhotoSyncStageStatus = 'pending' | 'running' | 'completed'

export interface PhotoSyncProgressState {
  dryRun: boolean
  summary: PhotoSyncResultSummary
  totals: PhotoSyncStageTotals
  stages: Record<
    PhotoSyncProgressStage,
    {
      status: PhotoSyncStageStatus
      processed: number
      total: number
    }
  >
  startedAt: number
  updatedAt: number
  logs: PhotoSyncLogEntry[]
  lastAction?: {
    stage: PhotoSyncProgressStage
    index: number
    total: number
    action: PhotoSyncAction
  }
  error?: string
}

export interface PhotoSyncLogEntry {
  id: string
  timestamp: number
  level: PhotoSyncLogLevel
  message: string
  stage?: PhotoSyncProgressStage | null
  storageKey?: string
  details?: Record<string, unknown> | null
}

export interface PhotoAssetManifestPayload {
  version: string
  data: PhotoManifestItem
}

export interface PhotoAssetListItem {
  id: string
  photoId: string
  storageKey: string
  storageProvider: string
  manifest: PhotoAssetManifestPayload
  syncedAt: string
  updatedAt: string
  createdAt: string
  publicUrl: string | null
  size: number | null
  syncStatus: 'pending' | 'synced' | 'conflict'
}

export interface PhotoAssetSummary {
  total: number
  synced: number
  conflicts: number
  pending: number
}

export type BillingUsageEventType = 'photo.asset.created' | 'photo.asset.deleted' | 'data.sync.completed'

export type BillingUsageUnit = 'count' | 'byte'

export interface BillingUsageEvent {
  id: string
  tenantId: string
  eventType: BillingUsageEventType
  quantity: number
  unit: BillingUsageUnit
  metadata: Record<string, unknown> | null
  occurredAt: string
  createdAt: string
  updatedAt: string
}

export interface BillingUsageTotalsEntry {
  eventType: BillingUsageEventType
  totalQuantity: number
  unit: BillingUsageUnit
}

export interface BillingUsageOverview {
  events: BillingUsageEvent[]
  totals: BillingUsageTotalsEntry[]
}
