import { ILeadSource, NormalizedLead, SearchParams, SourceCategory } from "./types";
import { z } from "zod";
import { getApiKey } from "../settings";

export class ApifySource implements ILeadSource {
  id = "apify";
  name = "Apify Managed Scraper";
  description = "Deep web scraping via Apify actors. Provides highly detailed contact info, social media, and business data.";
  category: SourceCategory = "scraping";

  inputSchema = z.object({
    keyword: z.string().min(1, "Search keyword is required"),
    location: z.string().min(1, "Location is required"),
    limit: z.number().optional().default(20),
    deepScrape: z.boolean().optional().default(false),
  });

  async run(params: SearchParams): Promise<NormalizedLead[]> {
    const apiToken = await getApiKey('apify');
    if (!apiToken) {
      throw new Error("Apify API token is missing. Please set APIFY_API_TOKEN in your settings.");
    }

    try {
      // We use the Google Maps Scraper actor as a default for "real world data"
      // Actor: apify/google-maps-scraper
      const actorId = "apify/google-maps-scraper";
      const runUrl = `https://api.apify.com/v2/acts/${actorId}/runs?token=${apiToken}&wait=60`;

      const input = {
        searchStringsArray: [`${params.keyword} in ${params.location}`],
        maxCrawledPlacesPerSearch: params.limit || 20,
        language: "en",
        proxyConfiguration: { useApifyProxy: true },
        // Deep scrape options if needed
        includeReviews: params.deepScrape,
        includeImages: false,
      };

      const runResponse = await fetch(runUrl, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(input),
      });

      if (!runResponse.ok) {
        const error = await runResponse.json();
        throw new Error(`Apify Run Error: ${error.error?.message || runResponse.statusText}`);
      }

      const runData = await runResponse.json();
      const datasetId = runData.data.defaultDatasetId;

      // Fetch results from dataset
      const datasetUrl = `https://api.apify.com/v2/datasets/${datasetId}/items?token=${apiToken}`;
      const datasetResponse = await fetch(datasetUrl);
      
      if (!datasetResponse.ok) {
        throw new Error("Failed to fetch results from Apify dataset.");
      }

      const items = await datasetResponse.json();

      return items.map((item: any) => ({
        businessName: item.title || item.name,
        website: item.website,
        phone: item.phone,
        email: item.email, // Some actors find emails automagically
        address: item.address,
        city: item.city || params.location,
        state: item.state,
        country: item.countryCode,
        category: item.categoryName,
        confidenceScore: 0.95,
        rawData: item,
      }));
    } catch (error) {
      console.error("Apify search failed:", error);
      throw error;
    }
  }

  async isAvailable(): Promise<boolean> {
    const apiToken = await getApiKey('apify');
    return !!apiToken;
  }
}
