import { GoogleGenAI, Type } from "@google/genai";
import { UserProgress } from "../types";

export interface LEIResult {
  score: number;
  category: 'Active Learner' | 'Consistent Learner' | 'Needs Support' | 'Stalled Learner';
  insight: string;
}

export async function calculateLEI(progress: UserProgress): Promise<LEIResult> {
  const apiKey = process.env.GEMINI_API_KEY;
  if (!apiKey) {
    // Fallback if no API key
    const score = calculateManualLEI(progress);
    return {
      score,
      category: getLEICategory(score),
      insight: "AI insight unavailable. Manual calculation used."
    };
  }

  const ai = new GoogleGenAI({ apiKey });
  
  const completedTracksCount = Object.values(progress.completedTracks).filter(Boolean).length;
  const metrics = {
    attempts: progress.totalAttempts,
    timeSpent: progress.timeSpent,
    completedTracks: completedTracksCount,
    retries: progress.retries || 0,
    hintsUsed: progress.hintsUsed,
    streak: progress.streak,
    xp: progress.xp
  };

  try {
    const response = await ai.models.generateContent({
      model: "gemini-3-flash-preview",
      contents: `Analyze the following student learning metrics and calculate a Learning Efficiency Index (LEI) score (0-100).
      
      Metrics:
      - Total Coding Attempts: ${metrics.attempts}
      - Total Time Spent (minutes): ${metrics.timeSpent}
      - Completed Learning Tracks: ${metrics.completedTracks} (out of 12)
      - Retry Count: ${metrics.retries}
      - Hints Used: ${metrics.hintsUsed}
      - Daily Activity Streak: ${metrics.streak}
      
      Calculation Rules:
      - Completion (Basics + Tracks) -> 30% weight
      - Effort (Attempts + Retries) -> 25% weight
      - Consistency (Daily usage / streak) -> 20% weight
      - Time Spent -> 15% weight
      - Hint usage -> -10% penalty
      
      Categories:
      - 80-100: Active Learner
      - 60-79: Consistent Learner
      - 40-59: Needs Support
      - 0-39: Stalled Learner
      
      Return a JSON object with:
      {
        "score": number (0-100),
        "category": "Active Learner" | "Consistent Learner" | "Needs Support" | "Stalled Learner",
        "insight": "A short (1-2 sentence) insight about the student's learning behavior"
      }`,
      config: {
        responseMimeType: "application/json",
        responseSchema: {
          type: Type.OBJECT,
          properties: {
            score: { type: Type.NUMBER },
            category: { type: Type.STRING },
            insight: { type: Type.STRING }
          },
          required: ["score", "category", "insight"]
        }
      }
    });

    const result = JSON.parse(response.text);
    return {
      score: Math.min(100, Math.max(0, result.score)),
      category: result.category,
      insight: result.insight
    };
  } catch (error) {
    console.error("LEI Calculation failed:", error);
    const score = calculateManualLEI(progress);
    return {
      score,
      category: getLEICategory(score),
      insight: "Error generating AI insight. Manual calculation used."
    };
  }
}

function calculateManualLEI(progress: UserProgress): number {
  const completedTracksCount = Object.values(progress.completedTracks).filter(Boolean).length;
  
  // Normalization factors (estimated)
  const completionScore = (completedTracksCount / 12) * 100;
  const effortScore = Math.min(100, ((progress.totalAttempts + (progress.retries || 0)) / 40) * 100);
  const consistencyScore = Math.min(100, (progress.streak / 7) * 100);
  const timeScore = Math.min(100, (progress.timeSpent / 300) * 100);
  const hintPenalty = Math.min(100, (progress.hintsUsed / 10) * 100);

  const finalScore = (
    (completionScore * 0.3) +
    (effortScore * 0.25) +
    (consistencyScore * 0.2) +
    (timeScore * 0.15) -
    (hintPenalty * 0.1)
  );

  return Math.round(Math.min(100, Math.max(0, finalScore)));
}

function getLEICategory(score: number): LEIResult['category'] {
  if (score >= 80) return 'Active Learner';
  if (score >= 60) return 'Consistent Learner';
  if (score >= 40) return 'Needs Support';
  return 'Stalled Learner';
}
