import { NextRequest, NextResponse } from "next/server";
import { processJobs, type Job } from "@/lib/queue/job-queue";
import {
  handleDemoReminderJob,
  handleTrialReminderJob,
  handleEmailJob,
  handleWebVitalsAlertJob,
  handleDepositReminderJob,
  type EmailPayload,
  type WebVitalsAlertPayload,
} from "@/lib/jobs/handlers";
import { logger } from "@/lib/logger";
import { getDataSource } from "@/lib/data-source";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

function isAuthorized(req: NextRequest): boolean {
  const cronSecret = process.env.CRON_SECRET;

  // In development with no CRON_SECRET configured, allow all local requests
  if (!cronSecret) {
    return process.env.NODE_ENV === "development";
  }

  const authHeader = req.headers.get("authorization");
  return authHeader === `Bearer ${cronSecret}`;
}

async function handle(job: Job): Promise<void> {
  switch (job.type) {
    case "demo_reminder":
      return handleDemoReminderJob(job.payload as { bookingId: string });
    case "trial_reminder":
      return handleTrialReminderJob(
        job.payload as { subscriptionId: string; daysRemaining: 1 | 3 },
      );
    case "email":
      return handleEmailJob(job.payload as EmailPayload);
    case "web_vitals_alert":
      return handleWebVitalsAlertJob(job.payload as WebVitalsAlertPayload);
    case "deposit_reminder":
      return handleDepositReminderJob(job.payload as { bookingId: string });
    default:
      throw new Error(`Unsupported job type: ${job.type}`);
  }
}

export async function GET(req: NextRequest) {
  if (!isAuthorized(req)) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const start = Date.now();

  try {
    // Convex data-source routing (WU-18)
    // When workflows domain is on Convex, job queue reads/writes
    // are routed through Convex sync_queue table.
    // The job handlers (email, demo reminder, etc.) remain unchanged.
    if (getDataSource("workflows") === "convex") {
      try {
        const { convexQuery } = await import("@/lib/convex-client");
        const pendingJobs = await convexQuery(
          "workflows/queries:getPendingJobs",
          {
            limit: 50,
          },
        );
        if (pendingJobs !== null) {
          logger.info("[Convex] Pending jobs check", {
            count: (pendingJobs as unknown[]).length,
          });
          // Note: actual job processing still uses the existing queue;
          // full Convex routing requires updating job-queue.ts
        }
      } catch {
        // Fall through to Prisma-backed queue
      }
    }

    const result = await processJobs(handle, { maxJobs: 50 });

    const duration = Date.now() - start;
    logger.info("Job worker run completed", {
      ...result,
      durationMs: duration,
    });

    return NextResponse.json({
      success: true,
      durationMs: duration,
      ...result,
    });
  } catch (error) {
    logger.error("Job worker run failed", error);
    return NextResponse.json(
      { success: false, error: String(error) },
      { status: 500 },
    );
  }
}

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