import { NextResponse } from "next/server";
import { logger } from "@/lib/logger";
import { createClient, getSupabaseAdmin } from "@/lib/supabase/server";
import { sendSms, isValidAuMobile } from "@/lib/sms";
import { sendEmail } from "@/lib/email";
import { HTTP_STATUS_INTERNAL_SERVER_ERROR } from "@/lib/constants";

type Alert = {
  id: string;
  severity: "critical" | "warning" | "info";
  title: string;
  message: string;
  metric: string;
  value: number | string;
  threshold: number | string;
  triggeredAt: string;
};

/**
 * GET /api/admin/alerts
 *
 * Check all critical launch metrics and return active alerts.
 * Designed to be polled every 15 minutes (by cron or dashboard).
 */
export async function GET() {
  try {
    const supabase = await createClient();
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const alerts = await runAlertChecks();
    return NextResponse.json({ alerts, checkedAt: new Date().toISOString() });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Unknown error";
    logger.error("Alerts API error:", message);
    return NextResponse.json({ error: "Failed to check alerts" }, { status: HTTP_STATUS_INTERNAL_SERVER_ERROR });
  }
}

/**
 * POST /api/admin/alerts
 *
 * Run alert checks AND send notifications for critical/warning alerts.
 * Called by cron job or manual trigger. No auth required for cron
 * but protected by secret header.
 */
export async function POST(request: Request) {
  try {
    const authHeader = request.headers.get("x-alert-secret");
    const expectedSecret = process.env.ALERT_CRON_SECRET || "rateright-alerts-2026";

    // Allow authenticated users OR cron secret
    if (authHeader !== expectedSecret) {
      const supabase = await createClient();
      const { data: { user } } = await supabase.auth.getUser();
      if (!user) {
        return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
      }
    }

    const alerts = await runAlertChecks();
    const notifications = await sendAlertNotifications(alerts);

    return NextResponse.json({
      alerts,
      notifications,
      checkedAt: new Date().toISOString(),
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Unknown error";
    logger.error("Alert notification error:", message);
    return NextResponse.json({ error: "Failed to process alerts" }, { status: HTTP_STATUS_INTERNAL_SERVER_ERROR });
  }
}

async function runAlertChecks(): Promise<Alert[]> {
  const admin = getSupabaseAdmin();
  const now = new Date();
  const alerts: Alert[] = [];

  const twentyFourHoursAgo = new Date(now);
  twentyFourHoursAgo.setHours(twentyFourHoursAgo.getHours() - 24);

  const fortyEightHoursAgo = new Date(now);
  fortyEightHoursAgo.setHours(fortyEightHoursAgo.getHours() - 48);

  const sevenDaysAgo = new Date(now);
  sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

  // Run all checks in parallel
  const [
    totalWorkers,
    recentWorkers,
    recentJobs,
    paymentsCharged,
    paymentsTotal,
    openUrgentIssues,
    serverHealth,
  ] = await Promise.all([
    // Total worker supply
    admin.from("worker_profiles").select("id", { count: "exact", head: true }),

    // Workers in last 24h
    admin.from("worker_profiles").select("id", { count: "exact", head: true })
      .gte("created_at", twentyFourHoursAgo.toISOString()),

    // Jobs in last 48h
    admin.from("jobs").select("id", { count: "exact", head: true })
      .gte("created_at", fortyEightHoursAgo.toISOString()),

    // Successful payments (7d)
    admin.from("payments").select("id", { count: "exact", head: true })
      .in("status", ["charged", "paid"])
      .gte("created_at", sevenDaysAgo.toISOString()),

    // Total payments (7d)
    admin.from("payments").select("id", { count: "exact", head: true })
      .gte("created_at", sevenDaysAgo.toISOString()),

    // Urgent open issues
    admin.from("issue_reports").select("id", { count: "exact", head: true })
      .eq("is_urgent", true)
      .neq("status", "resolved")
      .neq("status", "closed"),

    // App health check
    fetch("http://localhost:3000/api/health", { signal: AbortSignal.timeout(5000) })
      .then((r) => ({ ok: r.ok, status: r.status }))
      .catch(() => ({ ok: false, status: 0 })),
  ]);

  // 1. Worker supply = 0
  const workerCount = totalWorkers.count || 0;
  if (workerCount === 0) {
    alerts.push({
      id: "worker-supply-zero",
      severity: "critical",
      title: "Zero Worker Supply",
      message: "No workers registered on the platform. Matching is impossible.",
      metric: "total_workers",
      value: 0,
      threshold: "> 0",
      triggeredAt: now.toISOString(),
    });
  }

  // 2. Payment success rate < 90%
  const chargedCount = paymentsCharged.count || 0;
  const totalPaymentCount = paymentsTotal.count || 0;
  if (totalPaymentCount > 0) {
    const successRate = Math.round((chargedCount / totalPaymentCount) * 100);
    if (successRate < 90) {
      alerts.push({
        id: "payment-success-low",
        severity: "critical",
        title: "Low Payment Success Rate",
        message: `Payment success rate is ${successRate}% (${chargedCount}/${totalPaymentCount}). Revenue at risk.`,
        metric: "payment_success_rate",
        value: successRate,
        threshold: ">= 90%",
        triggeredAt: now.toISOString(),
      });
    }
  }

  // 3. No new workers in 24h
  const recentWorkerCount = recentWorkers.count || 0;
  if (recentWorkerCount === 0 && workerCount > 0) {
    alerts.push({
      id: "worker-signups-stalled",
      severity: "warning",
      title: "No New Workers (24h)",
      message: "Zero worker signups in the last 24 hours. Distribution may be failing.",
      metric: "workers_24h",
      value: 0,
      threshold: "> 0",
      triggeredAt: now.toISOString(),
    });
  }

  // 4. No job postings in 48h
  const recentJobCount = recentJobs.count || 0;
  if (recentJobCount === 0) {
    alerts.push({
      id: "job-postings-stalled",
      severity: "warning",
      title: "No Job Postings (48h)",
      message: "Zero job postings in the last 48 hours. Contractor engagement may be dropping.",
      metric: "jobs_48h",
      value: 0,
      threshold: "> 0",
      triggeredAt: now.toISOString(),
    });
  }

  // 5. App server health
  if (!serverHealth.ok) {
    alerts.push({
      id: "server-health-down",
      severity: "critical",
      title: "App Server Unhealthy",
      message: `Health check failed with status ${serverHealth.status}. App may be down.`,
      metric: "server_health",
      value: serverHealth.status,
      threshold: "200",
      triggeredAt: now.toISOString(),
    });
  }

  // 6. Urgent unresolved issues
  const urgentCount = openUrgentIssues.count || 0;
  if (urgentCount > 0) {
    alerts.push({
      id: "urgent-issues-open",
      severity: "warning",
      title: `${urgentCount} Urgent Issue${urgentCount !== 1 ? "s" : ""} Open`,
      message: `There are ${urgentCount} unresolved urgent issues (safety/critical).`,
      metric: "urgent_issues",
      value: urgentCount,
      threshold: "0",
      triggeredAt: now.toISOString(),
    });
  }

  return alerts;
}

async function sendAlertNotifications(alerts: Alert[]): Promise<{ sent: string[]; skipped: string[] }> {
  const sent: string[] = [];
  const skipped: string[] = [];

  const criticalAlerts = alerts.filter((a) => a.severity === "critical");
  const warningAlerts = alerts.filter((a) => a.severity === "warning");

  if (alerts.length === 0) {
    return { sent: ["no-alerts"], skipped: [] };
  }

  // Email for all alerts
  const adminEmail = process.env.ADMIN_EMAIL || process.env.SUPPORT_EMAIL;
  if (adminEmail) {
    try {
      const subject = criticalAlerts.length > 0
        ? `🚨 RateRight: ${criticalAlerts.length} CRITICAL alert${criticalAlerts.length !== 1 ? "s" : ""}`
        : `⚠️ RateRight: ${warningAlerts.length} warning${warningAlerts.length !== 1 ? "s" : ""}`;

      const body = alerts
        .map((a) => `[${a.severity.toUpperCase()}] ${a.title}\n${a.message}\nMetric: ${a.metric} = ${a.value} (threshold: ${a.threshold})`)
        .join("\n\n---\n\n");

      const htmlBody = alerts
        .map((a) => `<div style="margin-bottom:16px;padding:12px;border-left:4px solid ${a.severity === "critical" ? "#dc2626" : "#f59e0b"};background:#f9f9f9"><strong>[${a.severity.toUpperCase()}] ${a.title}</strong><br/>${a.message}<br/><small>Metric: ${a.metric} = ${a.value} (threshold: ${a.threshold})</small></div>`)
        .join("");
      await sendEmail(adminEmail, subject, htmlBody);
      sent.push("email");
    } catch (err) {
      logger.error("Alert email failed:", err);
      skipped.push("email");
    }
  } else {
    skipped.push("email-no-config");
  }

  // SMS for critical (revenue-risk) only
  const rockyPhone = process.env.ADMIN_PHONE;
  if (criticalAlerts.length > 0 && rockyPhone && isValidAuMobile(rockyPhone)) {
    try {
      const smsBody = `RateRight ALERT: ${criticalAlerts.map((a) => a.title).join(", ")}. Check /admin/launch-metrics now.`;
      await sendSms(rockyPhone, smsBody);
      sent.push("sms");
    } catch (err) {
      logger.error("Alert SMS failed:", err);
      skipped.push("sms");
    }
  }

  return { sent, skipped };
}
