import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { PDFDocument, PDFPage, rgb } from "pdf-lib";
import { startOfMonth, endOfMonth, format } from "date-fns";
import { fr } from "date-fns/locale";

const TEAL = rgb(0.08, 0.64, 0.64); // #14a4a4 - Diabetix teal
const TEAL_LIGHT = rgb(0.80, 0.95, 0.95); // Light teal background
const GRAY_DARK = rgb(0.15, 0.15, 0.15); // Dark gray text
const GRAY_LIGHT = rgb(0.62, 0.62, 0.62); // Light gray
const WHITE = rgb(1, 1, 1);
const RED = rgb(0.95, 0.26, 0.21); // For hypoglycemia
const GREEN = rgb(0.30, 0.77, 0.46); // For normal
const ORANGE = rgb(1, 0.59, 0.16); // For hyperglycemia

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

  const userId = session.user.id;

  try {
    const user = await prisma.user.findUnique({
      where: { id: userId },
      include: { patient: true },
    });

    if (!user) {
      return NextResponse.json({ error: "User not found" }, { status: 404 });
    }

    const searchParams = request.nextUrl.searchParams;
    const month = searchParams.get("month") ? new Date(searchParams.get("month")!) : new Date();

    const startDate = startOfMonth(month);
    const endDate = endOfMonth(month);

    const readings = await prisma.reading.findMany({
      where: {
        userId,
        measuredAt: {
          gte: startDate,
          lte: endDate,
        },
      },
      orderBy: { measuredAt: "asc" },
    });

    if (readings.length === 0) {
      return NextResponse.json(
        { error: "No readings found for this period" },
        { status: 404 }
      );
    }

    const doc = await PDFDocument.create();
    let page = doc.addPage([595, 842]); // A4
    let y = 750;

    const monthFormatted = format(month, "MMMM yyyy", { locale: fr });
    const todayFormatted = format(new Date(), "dd MMMM yyyy", { locale: fr });

    // Header with Diabetix branding
    page.drawRectangle({
      x: 0,
      y: 770,
      width: 595,
      height: 72,
      color: TEAL,
    });

    page.drawText("Diabetix", { x: 50, y: 810, size: 32, color: WHITE });
    page.drawText("Rapport Glycémie Mensuel", { x: 50, y: 785, size: 14, color: TEAL_LIGHT });

    y = 740;

    // Patient Information Section
    page.drawRectangle({
      x: 50,
      y: y - 120,
      width: 495,
      height: 120,
      color: TEAL_LIGHT,
      borderColor: TEAL,
      borderWidth: 1.5,
    });

    page.drawText("INFORMATIONS PATIENT", { x: 60, y: y - 15, size: 10, color: TEAL });
    y -= 35;

    if (user.patient) {
      page.drawText(`${user.patient.firstName} ${user.patient.lastName}`, { x: 60, y: y, size: 12, color: GRAY_DARK });
      y -= 18;
      page.drawText(`Email: ${user.email}`, { x: 60, y: y, size: 9, color: GRAY_LIGHT });
      y -= 15;
      page.drawText(`Type de diabète: ${user.patient.diabetesType || "Non spécifié"}`, { x: 60, y: y, size: 9, color: GRAY_LIGHT });
      y -= 15;
      page.drawText(`Traitement: ${user.patient.treatment || "Non spécifié"}`, { x: 60, y: y, size: 9, color: GRAY_LIGHT });
    }

    y = 610;

    // Report Period
    page.drawText(`Période: ${monthFormatted}`, { x: 50, y: y, size: 11, color: GRAY_DARK });
    page.drawText(`Généré le: ${todayFormatted}`, { x: 300, y: y, size: 11, color: GRAY_DARK });
    y -= 30;

    // Statistics Section
    page.drawText("STATISTIQUES", { x: 50, y: y, size: 11, color: TEAL });
    y -= 20;

    const values = readings.map((r) => r.value);
    const avg = values.reduce((a, b) => a + b, 0) / values.length;
    const min = Math.min(...values);
    const max = Math.max(...values);
    const std = Math.sqrt(values.reduce((sum, val) => sum + Math.pow(val - avg, 2), 0) / values.length);

    // Stats in a grid
    const statBoxHeight = 60;
    const statBoxWidth = 110;
    const statBoxX = [50, 170, 290, 410];

    const stats = [
      { label: "Mesures", value: readings.length.toString() },
      { label: "Moyenne", value: `${avg.toFixed(2)}` },
      { label: "Min", value: `${min.toFixed(2)}` },
      { label: "Max", value: `${max.toFixed(2)}` },
    ];

    stats.forEach((stat, idx) => {
      page.drawRectangle({
        x: statBoxX[idx],
        y: y - statBoxHeight,
        width: statBoxWidth,
        height: statBoxHeight,
        color: TEAL_LIGHT,
        borderColor: TEAL,
        borderWidth: 1,
      });

      page.drawText(stat.value, { x: statBoxX[idx] + 10, y: y - 30, size: 14, color: TEAL });
      page.drawText(stat.label, { x: statBoxX[idx] + 10, y: y - 50, size: 9, color: GRAY_LIGHT });
    });

    y -= 85;
    page.drawText(`Écart-type: ${std.toFixed(2)} g/L`, { x: 50, y: y, size: 9, color: GRAY_LIGHT });
    y -= 25;

    // Distribution Section
    page.drawText("DISTRIBUTION DES MESURES", { x: 50, y: y, size: 11, color: TEAL });
    y -= 20;

    const hypoCount = readings.filter((r) => r.value < 0.7).length;
    const normalCount = readings.filter((r) => r.value >= 0.7 && r.value <= 1.8).length;
    const hyperCount = readings.filter((r) => r.value > 1.8).length;

    const distributions = [
      { label: "Hypoglycémies (<0.7)", value: hypoCount, percent: ((hypoCount / readings.length) * 100).toFixed(1), color: ORANGE },
      { label: "Normales (0.7-1.8)", value: normalCount, percent: ((normalCount / readings.length) * 100).toFixed(1), color: GREEN },
      { label: "Hyperglycémies (>1.8)", value: hyperCount, percent: ((hyperCount / readings.length) * 100).toFixed(1), color: ORANGE },
    ];

    distributions.forEach((dist) => {
      page.drawRectangle({
        x: 50,
        y: y - 20,
        width: 8,
        height: 8,
        color: dist.color,
      });
      page.drawText(`${dist.label}: ${dist.value} (${dist.percent}%)`, { x: 65, y: y - 18, size: 9, color: GRAY_DARK });
      y -= 18;
    });

    y -= 15;

    // Detailed Readings Table
    page.drawText("DÉTAIL DES MESURES", { x: 50, y: y, size: 11, color: TEAL });
    y -= 20;

    // Table header
    const headerY = y;
    page.drawRectangle({
      x: 50,
      y: headerY - 18,
      width: 495,
      height: 18,
      color: TEAL,
    });

    page.drawText("Date", { x: 60, y: headerY - 14, size: 8, color: WHITE });
    page.drawText("Heure", { x: 130, y: headerY - 14, size: 8, color: WHITE });
    page.drawText("Valeur", { x: 210, y: headerY - 14, size: 8, color: WHITE });
    page.drawText("Notes", { x: 280, y: headerY - 14, size: 8, color: WHITE });

    y = headerY - 25;

    // Table rows
    readings.forEach((reading, idx) => {
      if (y < 60) {
        page = doc.addPage([595, 842]);
        y = 800;

        // Repeat header on new page
        page.drawRectangle({
          x: 50,
          y: y - 18,
          width: 495,
          height: 18,
          color: TEAL,
        });
        page.drawText("Date", { x: 60, y: y - 14, size: 8, color: WHITE });
        page.drawText("Heure", { x: 130, y: y - 14, size: 8, color: WHITE });
        page.drawText("Valeur", { x: 210, y: y - 14, size: 8, color: WHITE });
        page.drawText("Notes", { x: 280, y: y - 14, size: 8, color: WHITE });
        y -= 25;
      }

      const date = format(new Date(reading.measuredAt), "dd/MM/yyyy", { locale: fr });
      const time = format(new Date(reading.measuredAt), "HH:mm");
      const value = reading.value.toFixed(2);
      const notes = reading.notes?.substring(0, 30) || "";

      // Color based on glycemia level
      let rowColor = TEAL_LIGHT;
      let textColor = GRAY_DARK;

      if (reading.value < 0.7) {
        // Hypo - orange background
        rowColor = rgb(1, 0.92, 0.80); // light orange
        textColor = rgb(1, 0.59, 0.16); // darker orange text
      } else if (reading.value > 1.8) {
        // Hyper - orange background
        rowColor = rgb(1, 0.92, 0.80); // light orange
        textColor = rgb(1, 0.59, 0.16); // darker orange text
      } else if (idx % 2 === 0) {
        // Normal - alternate colors
        rowColor = TEAL_LIGHT;
      } else {
        rowColor = WHITE;
      }

      page.drawRectangle({
        x: 50,
        y: y - 16,
        width: 495,
        height: 16,
        color: rowColor,
      });

      page.drawText(date, { x: 60, y: y - 12, size: 8, color: textColor });
      page.drawText(time, { x: 130, y: y - 12, size: 8, color: textColor });
      page.drawText(value, { x: 210, y: y - 12, size: 8, color: textColor });
      page.drawText(notes, { x: 280, y: y - 12, size: 8, color: textColor });
      y -= 16;
    });

    const pdfBytes = await doc.save();
    const pdfBuffer = Buffer.from(pdfBytes);

    return new NextResponse(pdfBuffer, {
      headers: {
        "Content-Type": "application/pdf",
        "Content-Disposition": `attachment; filename="rapport_glycemie_${format(month, "yyyy-MM")}.pdf"`,
      },
    });
  } catch (error) {
    console.error("[generate-pdf]", error);
    return NextResponse.json(
      { error: "Failed to generate PDF" },
      { status: 500 }
    );
  }
}
