/**
 * Sync Engine Types
 *
 * @module @bytelyst/sync/types
 */

import type { ApiClient } from '@bytelyst/api-client';
import type { TelemetryClient } from '@bytelyst/telemetry-client';

// ─────────────────────────────────────────────────────────────────────────────
// Core Types
// ─────────────────────────────────────────────────────────────────────────────

export type EntityName = string;

export type ConflictStrategy = 'server-wins' | 'client-wins' | 'last-write-wins' | 'manual';

export type SyncStatus = 'idle' | 'syncing' | 'offline' | 'error';

export type SyncOperation = 'create' | 'update' | 'delete';

export interface EntityConfig {
  endpoint: string;
  partitionKey: string;
  conflictStrategy: ConflictStrategy;
}

export interface SyncEngineConfig {
  productId: string;
  entities: Record<EntityName, EntityConfig>;
  storage: StorageAdapter;
  apiClient: ApiClient;
  telemetryClient?: TelemetryClient;
  onConflict?: (local: SyncItem, remote: unknown) => Promise<unknown> | unknown;
  maxRetries?: number;
  retryDelayMs?: number;
}

export interface SyncItem {
  id: string;
  entity: EntityName;
  operation: SyncOperation;
  data: unknown;
  timestamp: string;
  retryCount: number;
  lastError?: string;
}

export interface SyncResult {
  success: boolean;
  pushed: number;
  pulled: number;
  conflicts: number;
  errors: number;
  timestamp: string;
}

export interface SyncStatusInfo {
  status: SyncStatus;
  queueLength: number;
  lastSyncAt?: string;
  lastError?: string;
}

export type SyncStatusCallback = (status: SyncStatusInfo) => void;

export interface Conflict {
  entity: EntityName;
  localItem: SyncItem;
  remoteData: unknown;
  localData: unknown;
}

// ─────────────────────────────────────────────────────────────────────────────
// Storage Adapter Interface
// ─────────────────────────────────────────────────────────────────────────────

export interface StorageAdapter {
  getItem<T>(key: string): Promise<T | null> | T | null;
  setItem<T>(key: string, value: T): Promise<void> | void;
  removeItem(key: string): Promise<void> | void;
  keys(): Promise<string[]> | string[];
}

// ─────────────────────────────────────────────────────────────────────────────
// Sync Engine Interface
// ─────────────────────────────────────────────────────────────────────────────

export interface SyncEngine {
  // Core operations
  push(entity: EntityName, data: unknown, operation?: SyncOperation): Promise<void>;
  delete(entity: EntityName, id: string): Promise<void>;
  pull(): Promise<SyncResult>;
  fullSync(): Promise<SyncResult>;

  // Status and monitoring
  getQueueLength(): number;
  getStatus(): SyncStatusInfo;
  onStatusChange(callback: SyncStatusCallback): () => void;

  // Utility
  clearQueue(): Promise<void>;
  reprocessFailed(): Promise<void>;
}
