import { NextRequest, NextResponse } from "next/server";
import { logger } from "@/lib/logger";
import { createClient, getSupabaseAdmin } from "@/lib/supabase/server";
import { HTTP_STATUS_INTERNAL_SERVER_ERROR } from "@/lib/constants";

/**
 * GET /api/admin/business-intelligence
 *
 * Unified business intelligence dashboard data.
 * Aggregates: workers, contractors, matches, payments, issues, fleet health.
 * Query params: ?days=7 (lookback period, default 7)
 */
export async function GET(request: NextRequest) {
  try {
    const supabase = await createClient();
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const admin = getSupabaseAdmin();
    const { searchParams } = new URL(request.url);
    const days = Math.min(Math.max(parseInt(searchParams.get("days") || "7", 10), 1), 90);

    const now = new Date();
    const periodStart = new Date(now);
    periodStart.setDate(now.getDate() - days);
    const periodStartISO = periodStart.toISOString();

    // Run all queries in parallel
    const [
      workersResult,
      contractorsResult,
      companiesResult,
      jobsResult,
      matchesResult,
      hiresResult,
      paymentsResult,
      issuesResult,
      recentWorkersResult,
      recentContractorsResult,
      recentJobsResult,
      workerTradesResult,
      workerCitiesResult,
    ] = await Promise.all([
      // Total workers
      admin
        .from("worker_profiles")
        .select("id", { count: "exact", head: true }),

      // Total contractor profiles
      admin
        .from("profiles")
        .select("id", { count: "exact", head: true })
        .eq("role", "contractor"),

      // Total companies
      admin
        .from("companies")
        .select("id", { count: "exact", head: true }),

      // Total jobs
      admin
        .from("jobs")
        .select("id, status", { count: "exact" }),

      // Total matches
      admin
        .from("matches")
        .select("id, status", { count: "exact" }),

      // Hires in period
      admin
        .from("matches")
        .select("id, hired_at, worker_id, jobs!inner(title, companies!inner(name))")
        .eq("status", "hired")
        .gte("hired_at", periodStartISO)
        .order("hired_at", { ascending: false }),

      // Payments in period
      admin
        .from("payments")
        .select("id, amount, status, created_at, stripe_payment_id")
        .gte("created_at", periodStartISO)
        .order("created_at", { ascending: false }),

      // Issues in period
      admin
        .from("issue_reports")
        .select("id, category, status, created_at, is_urgent")
        .gte("created_at", periodStartISO)
        .order("created_at", { ascending: false }),

      // Recent workers (period)
      admin
        .from("worker_profiles")
        .select("id, created_at")
        .gte("created_at", periodStartISO),

      // Recent contractor signups (period)
      admin
        .from("profiles")
        .select("id, created_at")
        .eq("role", "contractor")
        .gte("created_at", periodStartISO),

      // Recent jobs (period)
      admin
        .from("jobs")
        .select("id, created_at, status")
        .gte("created_at", periodStartISO),

      // Worker trades breakdown
      admin
        .from("worker_profiles")
        .select("primary_trade"),

      // Worker cities breakdown
      admin
        .from("worker_profiles")
        .select("city"),
    ]);

    // --- Aggregate data ---

    // Worker supply metrics
    const totalWorkers = workersResult.count || 0;
    const newWorkers = recentWorkersResult.data?.length || 0;

    // Trade breakdown
    const tradeCounts: Record<string, number> = {};
    for (const w of workerTradesResult.data || []) {
      const trade = w.primary_trade || "Unspecified";
      tradeCounts[trade] = (tradeCounts[trade] || 0) + 1;
    }
    const tradeBreakdown = Object.entries(tradeCounts)
      .map(([trade, count]) => ({ trade, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 10);

    // City breakdown
    const cityCounts: Record<string, number> = {};
    for (const w of workerCitiesResult.data || []) {
      const city = w.city || "Unknown";
      cityCounts[city] = (cityCounts[city] || 0) + 1;
    }
    const cityBreakdown = Object.entries(cityCounts)
      .map(([city, count]) => ({ city, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 10);

    // Contractor metrics
    const totalContractors = contractorsResult.count || 0;
    const totalCompanies = companiesResult.count || 0;
    const newContractors = recentContractorsResult.data?.length || 0;

    // Job metrics
    const totalJobs = jobsResult.count || 0;
    const jobsByStatus: Record<string, number> = {};
    for (const j of jobsResult.data || []) {
      const status = j.status || "unknown";
      jobsByStatus[status] = (jobsByStatus[status] || 0) + 1;
    }
    const newJobs = recentJobsResult.data?.length || 0;

    // Match/hire metrics
    const totalMatches = matchesResult.count || 0;
    const matchesByStatus: Record<string, number> = {};
    for (const m of matchesResult.data || []) {
      const status = m.status || "unknown";
      matchesByStatus[status] = (matchesByStatus[status] || 0) + 1;
    }
    const recentHires = hiresResult.data || [];
    const hireCount = recentHires.length;

    // Payment metrics
    const allPayments = paymentsResult.data || [];
    const chargedPayments = allPayments.filter((p) => p.status === "charged" || p.status === "paid");
    const pendingPayments = allPayments.filter((p) => p.status === "pending");
    const totalRevenue = chargedPayments.reduce((sum, p) => sum + (p.amount || 0), 0);
    const pendingRevenue = pendingPayments.reduce((sum, p) => sum + (p.amount || 0), 0);

    // Issue metrics
    const allIssues = issuesResult.data || [];
    const openIssues = allIssues.filter((i) => i.status !== "resolved" && i.status !== "closed");
    const urgentIssues = allIssues.filter((i) => i.is_urgent);
    const issuesByCategory: Record<string, number> = {};
    for (const i of allIssues) {
      const cat = i.category || "other";
      issuesByCategory[cat] = (issuesByCategory[cat] || 0) + 1;
    }

    // Supply/demand balance
    const supplyScore = Math.min(totalWorkers / Math.max(totalJobs, 1), 1) * 100;
    const demandScore = Math.min(totalJobs / Math.max(totalWorkers || 1, 1), 1) * 100;

    // Launch readiness composite (weighted)
    const hasWorkers = totalWorkers > 0 ? 20 : 0;
    const hasContractors = totalContractors > 0 ? 20 : 0;
    const hasJobs = totalJobs > 0 ? 15 : 0;
    const hasPayments = chargedPayments.length > 0 ? 15 : 0;
    const noUrgentIssues = urgentIssues.length === 0 ? 15 : 0;
    const hasMatches = totalMatches > 0 ? 15 : 0;
    const launchReadiness = hasWorkers + hasContractors + hasJobs + hasPayments + noUrgentIssues + hasMatches;

    // Fleet health (read from status files if available)
    let fleetHealth = null;
    try {
      const fs = await import("fs/promises");
      const fleetStatePath = "/home/ccuser/shared/fleet-state.json";
      const raw = await fs.readFile(fleetStatePath, "utf-8");
      const fleetState = JSON.parse(raw);
      fleetHealth = {
        agents: Object.entries(fleetState.agents || {}).map(([name, data]: [string, unknown]) => {
          const agent = data as { status?: string; current_task?: string; last_heartbeat?: string };
          return {
            name,
            status: agent.status || "unknown",
            currentTask: agent.current_task || null,
            lastHeartbeat: agent.last_heartbeat || null,
          };
        }),
        lastUpdated: fleetState.updated || null,
      };
    } catch {
      // Fleet state not available — non-critical
    }

    const response = {
      period: {
        from: periodStartISO,
        to: now.toISOString(),
        days,
      },
      supply: {
        totalWorkers,
        newWorkers,
        tradeBreakdown,
        cityBreakdown,
        supplyScore: Math.round(supplyScore),
      },
      demand: {
        totalContractors,
        totalCompanies,
        newContractors,
        totalJobs,
        newJobs,
        jobsByStatus,
        demandScore: Math.round(demandScore),
      },
      matching: {
        totalMatches,
        matchesByStatus,
        recentHires: recentHires.map((h) => ({
          id: h.id,
          hiredAt: h.hired_at,
          jobTitle: (h.jobs as unknown as { title: string })?.title,
          company: (h.jobs as unknown as { companies: { name: string } })?.companies?.name,
        })),
        hireCount,
        conversionRate: totalMatches > 0 ? Math.round((matchesByStatus["hired"] || 0) / totalMatches * 100) : 0,
      },
      payments: {
        total: allPayments.length,
        charged: chargedPayments.length,
        pending: pendingPayments.length,
        revenue: totalRevenue,
        pendingRevenue,
        successRate: allPayments.length > 0 ? Math.round(chargedPayments.length / allPayments.length * 100) : 0,
      },
      issues: {
        total: allIssues.length,
        open: openIssues.length,
        urgent: urgentIssues.length,
        byCategory: issuesByCategory,
      },
      fleet: fleetHealth,
      launchReadiness: {
        score: launchReadiness,
        breakdown: {
          workers: hasWorkers > 0,
          contractors: hasContractors > 0,
          jobs: hasJobs > 0,
          payments: hasPayments > 0,
          noUrgentIssues: noUrgentIssues > 0,
          matches: hasMatches > 0,
        },
      },
      generatedAt: now.toISOString(),
    };

    return NextResponse.json(response);
  } catch (error) {
    const message = error instanceof Error ? error.message : "Unknown error";
    logger.error("Business intelligence API error:", message);
    return NextResponse.json(
      { error: "Failed to fetch business intelligence data" },
      { status: HTTP_STATUS_INTERNAL_SERVER_ERROR }
    );
  }
}
