import { NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { getSession } from "@/lib/auth";

export async function GET() {
  const session = await getSession();
  if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const clinicId = session.id;
  const now = new Date();
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1);
  const weekAgo = new Date(); weekAgo.setDate(weekAgo.getDate() - 7);
  const monthAgo = new Date(); monthAgo.setDate(monthAgo.getDate() - 30);

  const [
    totalLeads, bookedLeads, confirmedLeads, arrivedLeads,
    completedLeads, noShowLeads, cancelledLeads,
    totalAppointments, upcomingAppointments,
    messagesSent, messagesDelivered, messagesRead, messagesFailed,
    leadsThisWeek, leadsLastWeek,
    appointmentsThisWeek,
  ] = await Promise.all([
    prisma.lead.count({ where: { clinicId } }),
    prisma.lead.count({ where: { clinicId, status: "booked" } }),
    prisma.lead.count({ where: { clinicId, status: "confirmed" } }),
    prisma.lead.count({ where: { clinicId, status: "arrived" } }),
    prisma.lead.count({ where: { clinicId, status: "completed" } }),
    prisma.lead.count({ where: { clinicId, status: "no_show" } }),
    prisma.lead.count({ where: { clinicId, status: "cancelled" } }),
    prisma.appointment.count({ where: { clinicId } }),
    prisma.appointment.count({
      where: { clinicId, dateTime: { gte: now }, status: { in: ["scheduled", "confirmed"] } },
    }),
    prisma.messageLog.count({ where: { clinicId, direction: "outgoing" } }),
    prisma.messageLog.count({ where: { clinicId, direction: "outgoing", status: "delivered" } }),
    prisma.messageLog.count({ where: { clinicId, direction: "outgoing", status: "read" } }),
    prisma.messageLog.count({ where: { clinicId, direction: "outgoing", status: "failed" } }),
    prisma.lead.count({ where: { clinicId, createdAt: { gte: weekAgo } } }),
    prisma.lead.count({ where: { clinicId, createdAt: { gte: new Date(weekAgo.getTime() - 7 * 86400000), lt: weekAgo } } }),
    prisma.appointment.count({ where: { clinicId, dateTime: { gte: weekAgo } } }),
  ]);

  const conversionRate = totalLeads > 0
    ? Math.round(((arrivedLeads + completedLeads) / totalLeads) * 100)
    : 0;
  const showUpRate = totalAppointments > 0
    ? Math.round(((arrivedLeads + completedLeads) / Math.max(arrivedLeads + completedLeads + noShowLeads, 1)) * 100)
    : 0;
  const confirmationRate = (bookedLeads + confirmedLeads + arrivedLeads + completedLeads) > 0
    ? Math.round(((confirmedLeads + arrivedLeads + completedLeads) / (bookedLeads + confirmedLeads + arrivedLeads + completedLeads)) * 100)
    : 0;
  const noShowRate = totalAppointments > 0
    ? Math.round((noShowLeads / Math.max(arrivedLeads + completedLeads + noShowLeads, 1)) * 100)
    : 0;
  const leadTrend = leadsLastWeek > 0
    ? Math.round(((leadsThisWeek - leadsLastWeek) / leadsLastWeek) * 100)
    : leadsThisWeek > 0 ? 100 : 0;

  // Today's appointments
  const todayAppointments = await prisma.appointment.findMany({
    where: { clinicId, dateTime: { gte: today, lt: tomorrow } },
    include: { lead: true, treatment: true, scheduledReminders: { orderBy: { scheduledFor: "asc" } } },
    orderBy: { dateTime: "asc" },
  });

  // Unconfirmed upcoming (need attention)
  const unconfirmedUpcoming = await prisma.appointment.findMany({
    where: { clinicId, dateTime: { gte: now }, status: "scheduled" },
    include: { lead: true, treatment: true },
    orderBy: { dateTime: "asc" },
    take: 5,
  });

  // Recent reminder activity
  const recentReminders = await prisma.scheduledReminder.findMany({
    where: { appointment: { clinicId }, status: { in: ["sent", "failed"] } },
    include: { template: true, appointment: { include: { lead: true } } },
    orderBy: { sentAt: "desc" },
    take: 8,
  });

  // Weekly heatmap: appointments per day for next 7 days — all 7 queries in parallel
  const next7Days = await Promise.all(
    Array.from({ length: 7 }, async (_, i) => {
      const dayStart = new Date(today);
      dayStart.setDate(dayStart.getDate() + i);
      const dayEnd = new Date(dayStart);
      dayEnd.setDate(dayEnd.getDate() + 1);
      const count = await prisma.appointment.count({
        where: { clinicId, dateTime: { gte: dayStart, lt: dayEnd }, status: { notIn: ["cancelled"] } },
      });
      return {
        date: dayStart.toISOString(),
        label: dayStart.toLocaleDateString("en-US", { weekday: "short" }),
        dayNum: dayStart.getDate(),
        count,
        isToday: i === 0,
      };
    })
  );

  // Treatments breakdown
  const treatmentStats = await prisma.appointment.groupBy({
    by: ["treatmentId"],
    where: { clinicId, createdAt: { gte: monthAgo } },
    _count: true,
  });
  const treatments = await prisma.treatment.findMany({
    where: { clinicId, id: { in: treatmentStats.map(t => t.treatmentId) } },
  });
  const treatmentBreakdown = treatmentStats.map(ts => {
    const t = treatments.find(tr => tr.id === ts.treatmentId);
    return { name: t?.name || "Unknown", count: ts._count, price: t?.price || 0 };
  }).sort((a, b) => b.count - a.count).slice(0, 5);

  // Revenue estimate
  const totalRevenue = treatmentBreakdown.reduce((sum, t) => sum + t.count * t.price, 0);

  // WhatsApp status + last health check (Upgrade #2 + #7)
  const clinic = await prisma.clinic.findUnique({
    where: { id: clinicId },
    select: { wahaStatus: true, wahaLastChecked: true, name: true },
  });

  // Upgrade #7: Cron monitoring for dashboard
  const lastCron = await prisma.cronLog.findFirst({
    where: { type: "send-reminders" },
    orderBy: { ranAt: "desc" },
  });

  const fiveMinAgo = new Date(now.getTime() - 5 * 60_000);
  const fifteenMinAgo = new Date(now.getTime() - 15 * 60_000);

  // Pending/failed reminder queue
  const [pendingReminders, failedReminders] = await Promise.all([
    prisma.scheduledReminder.count({
      where: { status: "pending", appointment: { clinicId } },
    }),
    prisma.scheduledReminder.count({
      where: { status: "failed", retryCount: { gte: 3 }, appointment: { clinicId } },
    }),
  ]);

  // Build system alerts
  const systemAlerts: { level: string; message: string }[] = [];

  if (clinic?.wahaStatus !== "connected") {
    systemAlerts.push({ level: "critical", message: `WhatsApp is ${clinic?.wahaStatus || "disconnected"}` });
  }
  if (!lastCron) {
    systemAlerts.push({ level: "critical", message: "Reminder cron has never run" });
  } else if (lastCron.ranAt < fifteenMinAgo) {
    systemAlerts.push({ level: "critical", message: `Cron hasn't run in ${Math.round((now.getTime() - lastCron.ranAt.getTime()) / 60_000)} min` });
  } else if (lastCron.ranAt < fiveMinAgo) {
    systemAlerts.push({ level: "warning", message: `Cron last ran ${Math.round((now.getTime() - lastCron.ranAt.getTime()) / 60_000)} min ago` });
  }
  if (failedReminders > 0) {
    systemAlerts.push({ level: "warning", message: `${failedReminders} reminders permanently failed` });
  }

  // Conversion funnel by lead source
  const sourceGroups = await prisma.lead.groupBy({
    by: ["source"],
    where: { clinicId },
    _count: true,
  });

  const sourceConversions = await Promise.all(
    sourceGroups.map(async (sg) => {
      const [converted, total] = await Promise.all([
        prisma.lead.count({
          where: { clinicId, source: sg.source, status: { in: ["arrived", "completed"] } },
        }),
        prisma.lead.count({ where: { clinicId, source: sg.source } }),
      ]);
      return {
        source: sg.source || "unknown",
        total,
        converted,
        conversionRate: total > 0 ? Math.round((converted / total) * 100) : 0,
      };
    })
  );

  return NextResponse.json({
    clinicName: clinic?.name,
    wahaStatus: clinic?.wahaStatus,
    wahaLastChecked: clinic?.wahaLastChecked,
    stats: {
      totalLeads, bookedLeads, confirmedLeads, arrivedLeads, completedLeads,
      noShowLeads, cancelledLeads, totalAppointments, upcomingAppointments,
      conversionRate, showUpRate, confirmationRate, noShowRate,
      messagesSent, messagesDelivered, messagesRead, messagesFailed,
      leadTrend, leadsThisWeek, appointmentsThisWeek, totalRevenue,
    },
    todayAppointments,
    unconfirmedUpcoming,
    recentReminders,
    next7Days,
    treatmentBreakdown,
    sourceFunnel: sourceConversions,
    // Upgrade #7: System health
    systemHealth: {
      cronLastRun: lastCron?.ranAt || null,
      cronStatus: !lastCron ? "never" : lastCron.ranAt >= fiveMinAgo ? "healthy" : lastCron.ranAt >= fifteenMinAgo ? "warning" : "critical",
      pendingReminders,
      failedReminders,
      alerts: systemAlerts,
    },
  });
}
