import { ISync, SyncStatus } from '../types/CalendarTypes';

/**
 * SyncPlugin<T extends ISync> - Pluggable sync functionality for entity services
 *
 * COMPOSITION PATTERN:
 * - Encapsulates all sync-related logic in separate class
 * - Composed into BaseEntityService (not inheritance)
 */
export class SyncPlugin<T extends ISync> {
  constructor(private service: any) {}

  /**
   * Mark entity as successfully synced
   */
  async markAsSynced(id: string): Promise<void> {
    const entity = await this.service.get(id);
    if (entity) {
      entity.syncStatus = 'synced';
      await this.service.save(entity);
    }
  }

  /**
   * Mark entity as sync error
   */
  async markAsError(id: string): Promise<void> {
    const entity = await this.service.get(id);
    if (entity) {
      entity.syncStatus = 'error';
      await this.service.save(entity);
    }
  }

  /**
   * Get current sync status for an entity
   */
  async getSyncStatus(id: string): Promise<SyncStatus | null> {
    const entity = await this.service.get(id);
    return entity ? entity.syncStatus : null;
  }

  /**
   * Get entities by sync status using IndexedDB index
   */
  async getBySyncStatus(syncStatus: string): Promise<T[]> {
    return new Promise((resolve, reject) => {
      const transaction = this.service.db.transaction([this.service.storeName], 'readonly');
      const store = transaction.objectStore(this.service.storeName);
      const index = store.index('syncStatus');
      const request = index.getAll(syncStatus);

      request.onsuccess = () => {
        const data = request.result as unknown[];
        const entities = data.map(item => this.service.deserialize(item));
        resolve(entities);
      };

      request.onerror = () => {
        reject(new Error(`Failed to get by sync status ${syncStatus}: ${request.error}`));
      };
    });
  }
}
