import { GoogleGenerativeAI } from '@google/generative-ai';
import { NormalizationResult } from '../types';

/**
 * Uses AI to normalize search queries (correct typos, interpret intent).
 */
export async function normalizeQuery(keyword: string, location: string): Promise<NormalizationResult> {
  const result: NormalizationResult = {
    keyword,
    location,
    originalKeyword: keyword,
    originalLocation: location,
    isCorrected: false,
  };

  const apiKey = process.env.GEMINI_API_KEY;
  if (!apiKey) return result;

  try {
    const genAI = new GoogleGenerativeAI(apiKey);
    const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

    // Sanitize and handle empty inputs
    const safeKeyword = keyword ? String(keyword).trim() : "";
    const safeLocation = location ? String(location).trim() : "";
    
    if (!safeKeyword && !safeLocation) return result;

    const prompt = `
      You are an expert NLP system for a business lead generation and scraping tool. 
      Users frequently provide unstructured, conversational, or vague input. Your job is to parse their input and extract the core actionable "keyword" (business type, service, industry, or product) and the "location" (city, state, region, neighborhood, or zip).

      Raw Keyword Input: "${safeKeyword}"
      Raw Location Input: "${safeLocation}"

      Instructions:
      1. SENSITIVITY TO NATURAL LANGUAGE: If the Raw Keyword is a sentence (e.g., "Find me a good dentist in Los Angeles" or "Mexican restaurants close to NYC"), extract "dentist" or "Mexican restaurant" as the keyword, and extract "Los Angeles" or "NYC" as the location.
      2. MISSING LOCATION INFERENCE: If the Raw Location is empty but a location is mentioned in the Raw Keyword (e.g., Keyword: "Plumbers in Chicago", Location: ""), move "Chicago" to the location and keep "Plumbers" as the keyword.
      3. TYPO CORRECTION: Fix any spelling mistakes (e.g., "plmbr" -> "plumber").
      4. NORMALIZATION: Normalize locations to a standard, highly searchable format (e.g., "nyc" -> "New York, NY", "LA" -> "Los Angeles, CA").
      5. INTENT INFERENCE: If the input describes a problem rather than a profession (e.g., "places to fix my car engine"), translate it into the correct industry category (e.g., "auto repair" or "mechanic").
      6. GEOMETRY PRESERVATION: If the Raw Location Input is a set of coordinates (e.g., "40.71, -74.00" or "lat: 40, lng: -74") or includes a radius (e.g., "40.7, -74.0, 5000"), PRESERVE IT EXACTLY as the "location". Do NOT "normalize" it into a city name.
      7. DO NOT change the core meaning, just optimize it so traditional scraping APIs (like Google Places) can effectively search it.
      
      Return ONLY a valid JSON object in this exact format. DO NOT INCLUDE ANY markdown formatting (like \`\`\`json) or extra text. Only return the raw JSON object:
      {
        "keyword": "optimized keyword",
        "location": "optimized location",
        "isCorrected": true
      }
    `;

    const aiResult = await model.generateContent(prompt);
    const responseText = aiResult.response.text();
    
    // Extract JSON from response (handling potential markdown blocks)
    const jsonMatch = responseText.match(/\{[\s\S]*\}/);
    if (jsonMatch) {
      const parsed = JSON.parse(jsonMatch[0]);
      return {
        ...result,
        keyword: parsed.keyword ?? keyword,
        location: parsed.location ?? location,
        isCorrected: parsed.isCorrected ?? (parsed.keyword !== keyword || parsed.location !== location),
      };
    }
  } catch (error) {
    console.error('Normalization error:', error);
  }

  return result;
}
