import { NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { getSessionStatus, createSession } from "@/lib/waha";

/**
 * Upgrade #2: WhatsApp Health Monitor + Auto-Reconnect
 *
 * Run every 5 minutes to:
 * 1. Check Waha session status
 * 2. Update clinic.wahaStatus in DB
 * 3. Auto-reconnect if session dropped
 * 4. Log to CronLog for monitoring
 *
 * Setup: * /5 * * * * curl -s http://localhost:3000/api/cron/health-check?key=dev-cron-key
 */
export async function POST(req: Request) {
  const url = new URL(req.url);
  const key = url.searchParams.get("key");
  const cronKey = process.env.CRON_SECRET || "dev-cron-key";

  if (process.env.NODE_ENV === "production" && key !== cronKey) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const startTime = Date.now();
  const results: {
    checked: number;
    healthy: number;
    reconnected: number;
    errors: string[];
  } = { checked: 0, healthy: 0, reconnected: 0, errors: [] };

  try {
    // Find all clinics that have ever connected WhatsApp
    const clinics = await prisma.clinic.findMany({
      where: { wahaSessionId: { not: null } },
      select: { id: true, name: true, wahaSessionId: true, wahaStatus: true },
    });

    for (const clinic of clinics) {
      results.checked++;

      try {
        // Check actual Waha session status
        const session = await getSessionStatus();
        const actualStatus = session?.status || "STOPPED";

        let newDbStatus: string;
        if (actualStatus === "WORKING") {
          newDbStatus = "connected";
          results.healthy++;
        } else if (actualStatus === "SCAN_QR_CODE") {
          newDbStatus = "qr_pending";
        } else {
          newDbStatus = "disconnected";
        }

        // Update DB if status changed
        if (clinic.wahaStatus !== newDbStatus) {
          console.log(`📱 ${clinic.name}: ${clinic.wahaStatus} → ${newDbStatus} (actual: ${actualStatus})`);

          await prisma.clinic.update({
            where: { id: clinic.id },
            data: { wahaStatus: newDbStatus, wahaLastChecked: new Date() },
          });

          // Auto-reconnect if was connected but now disconnected
          if (clinic.wahaStatus === "connected" && newDbStatus === "disconnected") {
            console.log(`🔄 Auto-reconnecting WhatsApp for ${clinic.name}...`);
            try {
              await createSession();
              results.reconnected++;

              // Check again after reconnect attempt
              const recheckSession = await getSessionStatus();
              const recheckStatus = recheckSession?.status;
              if (recheckStatus === "WORKING") {
                await prisma.clinic.update({
                  where: { id: clinic.id },
                  data: { wahaStatus: "connected", wahaLastChecked: new Date() },
                });
                console.log(`✅ Auto-reconnected ${clinic.name} successfully`);
              } else if (recheckStatus === "SCAN_QR_CODE") {
                await prisma.clinic.update({
                  where: { id: clinic.id },
                  data: { wahaStatus: "qr_pending", wahaLastChecked: new Date() },
                });
                console.log(`⚠️ ${clinic.name} needs QR re-scan`);
              }
            } catch (reconnErr) {
              const msg = `Auto-reconnect failed for ${clinic.name}: ${reconnErr instanceof Error ? reconnErr.message : "Unknown"}`;
              console.error(`❌ ${msg}`);
              results.errors.push(msg);
            }
          }
        } else {
          // Status unchanged — just update lastChecked
          await prisma.clinic.update({
            where: { id: clinic.id },
            data: { wahaLastChecked: new Date() },
          });
        }
      } catch (err) {
        const msg = `Health check failed for ${clinic.name}: ${err instanceof Error ? err.message : "Unknown"}`;
        console.error(`❌ ${msg}`);
        results.errors.push(msg);

        // If we can't reach Waha at all, mark as disconnected
        if (clinic.wahaStatus === "connected") {
          await prisma.clinic.update({
            where: { id: clinic.id },
            data: { wahaStatus: "disconnected", wahaLastChecked: new Date() },
          });
        }
      }
    }

    // Re-queue reminders that failed due to WhatsApp being disconnected
    // BURST LIMIT: max 10 per health-check cycle to avoid message floods
    const failedDueToWA = await prisma.scheduledReminder.findMany({
      where: {
        status: "failed",
        failureReason: { contains: "WhatsApp not connected" },
        retryCount: { lt: 3 },
        appointment: { clinic: { wahaStatus: "connected" } },
      },
      orderBy: { scheduledFor: "asc" }, // oldest first
      take: 10, // BURST LIMIT
    });

    if (failedDueToWA.length > 0) {
      await prisma.scheduledReminder.updateMany({
        where: { id: { in: failedDueToWA.map(r => r.id) } },
        data: {
          status: "pending",
          nextRetryAt: new Date(),
          failureReason: null,
        },
      });
      console.log(`🔄 Re-queued ${failedDueToWA.length} reminders after WhatsApp reconnect (burst-limited)`);
    }

    const duration = Date.now() - startTime;

    // Log execution
    try {
      await prisma.cronLog.create({
        data: {
          type: "health-check",
          sent: results.healthy,
          failed: results.errors.length,
          retried: results.reconnected,
          durationMs: duration,
          error: results.errors.length > 0 ? results.errors.join("; ") : null,
        },
      });
    } catch { /* don't fail on logging */ }

    return NextResponse.json({
      success: true,
      ...results,
      durationMs: duration,
      checkedAt: new Date().toISOString(),
    });
  } catch (error) {
    console.error("❌ Health check fatal error:", error);
    return NextResponse.json(
      { error: "Health check failed", message: error instanceof Error ? error.message : "Unknown" },
      { status: 500 }
    );
  }
}

export async function GET(req: Request) {
  return POST(req);
}
