import { IApiRepository } from '../repositories/IApiRepository';
import { IEntityService } from '../storage/IEntityService';
import { ISync } from '../types/CalendarTypes';

/**
 * DataSeeder - Orchestrates initial data loading from repositories into IndexedDB
 *
 * ARCHITECTURE:
 * - Repository (Mock/Api): Fetches data from source (JSON file or backend API)
 * - DataSeeder (this class): Orchestrates fetch + save operations
 * - Service (EventService, etc.): Saves data to IndexedDB
 *
 * POLYMORPHIC DESIGN:
 * - Uses arrays of IEntityService[] and IApiRepository[]
 * - Matches services with repositories using entityType property
 * - Open/Closed Principle: Adding new entity requires no code changes here
 */
export class DataSeeder {
  constructor(
    private services: IEntityService<ISync>[],
    private repositories: IApiRepository<ISync>[]
  ) {}

  /**
   * Seed all entity stores if they are empty
   */
  async seedIfEmpty(): Promise<void> {
    console.log('[DataSeeder] Checking if database needs seeding...');

    try {
      for (const service of this.services) {
        const repository = this.repositories.find(repo => repo.entityType === service.entityType);

        if (!repository) {
          console.warn(`[DataSeeder] No repository found for entity type: ${service.entityType}, skipping`);
          continue;
        }

        await this.seedEntity(service.entityType, service, repository);
      }

      console.log('[DataSeeder] Seeding complete');
    } catch (error) {
      console.error('[DataSeeder] Seeding failed:', error);
      throw error;
    }
  }

  private async seedEntity<T extends ISync>(
    entityType: string,
    service: IEntityService<T>,
    repository: IApiRepository<T>
  ): Promise<void> {
    const existing = await service.getAll();

    if (existing.length > 0) {
      console.log(`[DataSeeder] ${entityType} store already has ${existing.length} items, skipping seed`);
      return;
    }

    console.log(`[DataSeeder] ${entityType} store is empty, fetching from repository...`);

    const data = await repository.fetchAll();

    console.log(`[DataSeeder] Fetched ${data.length} ${entityType} items, saving to IndexedDB...`);

    for (const entity of data) {
      await service.save(entity, true); // silent = true to skip audit logging
    }

    console.log(`[DataSeeder] ${entityType} seeding complete (${data.length} items saved)`);
  }
}
