import { LeadProvider } from './LeadProvider';
import { FoursquareProvider } from './FoursquareProvider';
import { OverpassProvider } from './OverpassProvider';
import { MockProvider } from './MockProvider';
import { Lead, SearchQuery } from '../types';

export class ProviderAggregator {
  private providers: LeadProvider[] = [];

  constructor() {
    // We conditionally add the providers to aggregate results from all sources that have access.
      // Always include MockProvider for a snappy UI experience and fallback data
      this.providers.push(new MockProvider());

      // Overpass (OpenStreetMap) is free and unauthenticated - always use it to provide real data!
      this.providers.push(new OverpassProvider());

      // If they provided API Key, we add that source too to enrich results
      if (process.env.FOURSQUARE_API_KEY) {
        this.providers.push(new FoursquareProvider());
      }
  }

  async searchAll(query: SearchQuery): Promise<Lead[]> {
    const results: Lead[] = [];
    const promises = this.providers.map(p => p.search(query));
    const allResults = await Promise.allSettled(promises);

    for (const result of allResults) {
      if (result.status === 'fulfilled') {
        results.push(...result.value);
      }
    }

    // Deduplicate by Name + Phone (basic deduplication)
    const uniqueMap = new Map<string, Lead>();
    for (const lead of results) {
      const key = `${lead.name.toLowerCase()}-${lead.phone}`;
      if (!uniqueMap.has(key)) {
        uniqueMap.set(key, lead);
      } else {
        // Merge higher quality score lead features if needed
        const existing = uniqueMap.get(key)!;
        if (lead.qualityScore > existing.qualityScore) {
          uniqueMap.set(key, { ...existing, ...lead, qualityScore: lead.qualityScore });
        }
      }
    }

    // Sort by quality score descending
    const sortedResults = Array.from(uniqueMap.values()).sort((a, b) => b.qualityScore - a.qualityScore);
    return sortedResults;
  }
}
