import { NextResponse } from "next/server";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { estimateHbA1c, statusFor, type Moment } from "@/lib/glycemia";
import { DIABETES_TYPE_LABELS, SEX_LABELS } from "@/lib/patient";
import { differenceInYears, isSameDay } from "date-fns";

async function generateAnalysis(userId: string): Promise<string> {
  const apiKey = process.env.GEMINI_API_KEY;
  if (!apiKey || apiKey === "your_gemini_api_key_here") {
    throw new Error("Clé API Gemini non configurée.");
  }

  const now = new Date();
  const ago7 = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
  const ago30 = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);

  const [patient, readings7, readings30, lastReading] = await Promise.all([
    prisma.patient.findUnique({ where: { userId } }),
    prisma.reading.findMany({ where: { userId, measuredAt: { gte: ago7 } } }),
    prisma.reading.findMany({ where: { userId, measuredAt: { gte: ago30 } } }),
    prisma.reading.findFirst({ where: { userId }, orderBy: { measuredAt: "desc" } }),
  ]);

  const avg7 = readings7.length
    ? readings7.reduce((s, r) => s + r.value, 0) / readings7.length
    : null;
  const avg30 = readings30.length
    ? readings30.reduce((s, r) => s + r.value, 0) / readings30.length
    : null;

  let inRange30 = 0, hypo30 = 0, hyper30 = 0;
  for (const r of readings30) {
    const s = statusFor(r.value, r.moment as Moment);
    if (s === "in-range") inRange30++;
    else if (s === "hypo") hypo30++;
    else hyper30++;
  }
  const inRangePct = readings30.length ? (inRange30 / readings30.length) * 100 : null;
  const hba1c = avg30 ? estimateHbA1c(avg30) : null;

  const age = patient?.birthDate ? differenceInYears(now, patient.birthDate) : null;
  const bmi =
    patient?.heightCm && patient?.weightKg
      ? patient.weightKg / Math.pow(patient.heightCm / 100, 2)
      : null;

  const prompt = `Tu es Diablo, coach diabète bienveillant. Rédige un court paragraphe d'analyse quotidienne (4 à 6 phrases max) pour ce patient.

Données patient :
- Prénom : ${patient?.firstName ?? "le patient"}
- Âge : ${age ? `${age} ans` : "non renseigné"}
- Type diabète : ${patient?.diabetesType ? (DIABETES_TYPE_LABELS[patient.diabetesType] ?? patient.diabetesType) : "non renseigné"}
- Traitement : ${patient?.treatment ?? "non renseigné"}
- IMC : ${bmi ? bmi.toFixed(1) : "non calculable"}
- Sexe : ${patient?.sex ? (SEX_LABELS[patient.sex] ?? patient.sex) : "non renseigné"}

Données glycémiques :
- Dernière mesure : ${lastReading ? `${lastReading.value.toFixed(2)} g/L (${lastReading.moment})` : "aucune"}
- Moyenne 7 jours : ${avg7 ? `${avg7.toFixed(2)} g/L (${readings7.length} relevés)` : "aucune donnée"}
- Moyenne 30 jours : ${avg30 ? `${avg30.toFixed(2)} g/L (${readings30.length} relevés)` : "aucune donnée"}
- % dans la cible (30j) : ${inRangePct ? `${inRangePct.toFixed(0)} %` : "aucune donnée"}
- Hypoglycémies (30j) : ${hypo30}
- Hyperglycémies (30j) : ${hyper30}
- HbA1c estimée : ${hba1c ? `${hba1c.toFixed(1)} %` : "aucune donnée"}

Consignes :
- Commence par une observation concrète sur les chiffres de la semaine
- Identifie une tendance positive et une piste d'amélioration si pertinent
- Termine par une phrase d'encouragement personnalisée
- Ton chaleureux, positif, jamais alarmiste
- Ne propose jamais de modifier un traitement médical
- Réponds en français, sans titre, sans liste — juste un paragraphe fluide
- 4 à 6 phrases maximum`;

  const genAI = new GoogleGenerativeAI(apiKey);
  const model = genAI.getGenerativeModel({ model: process.env.GEMINI_MODEL ?? "gemini-2.5-flash" });

  const result = await model.generateContent(prompt);
  return result.response.text().trim();
}

export async function GET(request: Request) {
  const session = await auth();
  if (!session?.user?.id) return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
  const userId = session.user.id;

  const plan = (session.user as { plan?: string }).plan ?? "FREE";
  if (plan !== "PREMIUM") {
    return NextResponse.json({ error: "L'analyse IA est réservée aux membres Premium." }, { status: 403 });
  }

  const url = new URL(request.url);
  const forceRefresh = url.searchParams.get("refresh") === "1";

  const existing = await prisma.dailyAnalysis.findUnique({ where: { userId } });

  const isStale =
    !existing ||
    forceRefresh ||
    !isSameDay(new Date(existing.generatedAt), new Date());

  if (!isStale && existing) {
    return NextResponse.json({ content: existing.content, generatedAt: existing.generatedAt, fresh: false });
  }

  try {
    const content = await generateAnalysis(userId);
    const record = await prisma.dailyAnalysis.upsert({
      where: { userId },
      create: { userId, content, generatedAt: new Date() },
      update: { content, generatedAt: new Date() },
    });
    return NextResponse.json({ content: record.content, generatedAt: record.generatedAt, fresh: true });
  } catch (err) {
    if (existing) {
      return NextResponse.json({
        content: existing.content,
        generatedAt: existing.generatedAt,
        fresh: false,
        warning: err instanceof Error ? err.message : "Erreur de génération",
      });
    }
    return NextResponse.json(
      { error: err instanceof Error ? err.message : "Erreur inconnue" },
      { status: 503 }
    );
  }
}
