import { NextRequest, NextResponse } from "next/server";
import { logger } from "@/lib/logger";
import { getSupabaseAdmin } from "@/lib/supabase/server";
import { sendSms, SMS_TEMPLATES, isValidAuMobile } from "@/lib/sms";
import { HTTP_STATUS_INTERNAL_SERVER_ERROR } from "@/lib/constants";
import { checkRateLimit, getClientIP, createRateLimitResponse } from "@/lib/rate-limit";

// Rate limit: 10 SMS triggers per 5 minutes per IP
const SMS_RATE_LIMIT = 10;
const SMS_WINDOW_MS = 5 * 60 * 1000;

type SmsEventType = "worker_applied" | "worker_hired" | "no_show_detected";

interface SmsNotificationRequest {
  event: SmsEventType;
  matchId: string;
}

/**
 * POST /api/notifications/sms
 * 
 * Internal API to trigger SMS notifications for key events.
 * Called server-side from other API routes (not directly by clients).
 * 
 * Events:
 * - worker_applied: SMS to contractor when a worker applies
 * - worker_hired: SMS to worker when they're hired
 * - no_show_detected: SMS to contractor about no-show + warning to worker
 */
export async function POST(request: NextRequest) {
  try {
    const clientIP = getClientIP(request);
    const rateLimit = await checkRateLimit(`sms:${clientIP}`, SMS_RATE_LIMIT, SMS_WINDOW_MS);
    if (!rateLimit.allowed) {
      const retryAfter = Math.ceil((rateLimit.resetTime - Date.now()) / 1000);
      return createRateLimitResponse(clientIP, retryAfter);
    }

    // Simple API key check for internal calls
    const authHeader = request.headers.get("x-internal-key");
    const internalKey = process.env.INTERNAL_API_KEY || process.env.TWILIO_AUTH_TOKEN;
    if (!authHeader || authHeader !== internalKey) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { event, matchId } = (await request.json()) as SmsNotificationRequest;

    if (!event || !matchId) {
      return NextResponse.json({ error: "Missing event or matchId" }, { status: 400 });
    }

    const admin = getSupabaseAdmin();

    // Fetch match with related data
    const { data: match, error: matchError } = await admin
      .from("matches")
      .select(`
        id, status, worker_id, no_show,
        jobs!inner(
          title, company_id, start_date,
          companies!inner(profile_id, name)
        )
      `)
      .eq("id", matchId)
      .single();

    if (matchError || !match) {
      logger.error("SMS notification: match not found", { matchId, error: matchError });
      return NextResponse.json({ error: "Match not found" }, { status: 404 });
    }

    const jobs = match.jobs as unknown as {
      title: string;
      company_id: string;
      start_date: string | null;
      companies: { profile_id: string; name: string };
    };

    const results: Array<{ to: string; success: boolean; error?: string }> = [];

    switch (event) {
      case "worker_applied": {
        // SMS to contractor
        const { data: contractorProfile } = await admin
          .from("profiles")
          .select("phone, name")
          .eq("id", jobs.companies.profile_id)
          .single();

        const { data: workerProfile } = await admin
          .from("profiles")
          .select("name")
          .eq("id", match.worker_id)
          .single();

        if (contractorProfile?.phone && isValidAuMobile(contractorProfile.phone)) {
          const body = SMS_TEMPLATES.workerApplied(
            jobs.title,
            workerProfile?.name || "A worker"
          );
          const result = await sendSms(contractorProfile.phone, body);
          results.push({
            to: "contractor",
            success: result.success,
            error: result.error,
          });
        }
        break;
      }

      case "worker_hired": {
        // SMS to worker
        const { data: workerProfile } = await admin
          .from("profiles")
          .select("phone")
          .eq("id", match.worker_id)
          .single();

        if (workerProfile?.phone && isValidAuMobile(workerProfile.phone)) {
          const body = SMS_TEMPLATES.workerHired(
            jobs.title,
            jobs.companies.name || "A contractor"
          );
          const result = await sendSms(workerProfile.phone, body);
          results.push({
            to: "worker",
            success: result.success,
            error: result.error,
          });
        }
        break;
      }

      case "no_show_detected": {
        // SMS to contractor about no-show
        const { data: contractorProfile } = await admin
          .from("profiles")
          .select("phone, name")
          .eq("id", jobs.companies.profile_id)
          .single();

        const { data: workerProfile } = await admin
          .from("profiles")
          .select("phone, name")
          .eq("id", match.worker_id)
          .single();

        if (contractorProfile?.phone && isValidAuMobile(contractorProfile.phone)) {
          const body = SMS_TEMPLATES.noShowDetected(
            jobs.title,
            workerProfile?.name || "The worker"
          );
          const result = await sendSms(contractorProfile.phone, body);
          results.push({
            to: "contractor",
            success: result.success,
            error: result.error,
          });
        }

        // Warning SMS to worker
        if (workerProfile?.phone && isValidAuMobile(workerProfile.phone)) {
          const body = SMS_TEMPLATES.noShowWarning(jobs.title);
          const result = await sendSms(workerProfile.phone, body);
          results.push({
            to: "worker",
            success: result.success,
            error: result.error,
          });
        }
        break;
      }

      default:
        return NextResponse.json({ error: `Unknown event: ${event}` }, { status: 400 });
    }

    logger.info(`SMS notifications sent for ${event}`, { matchId, results });
    return NextResponse.json({ success: true, results });
  } catch (error) {
    logger.error("SMS notification error:", error);
    return NextResponse.json(
      { error: "Failed to send SMS notification" },
      { status: HTTP_STATUS_INTERNAL_SERVER_ERROR }
    );
  }
}
