import { NextRequest, NextResponse } from "next/server";
import { logger } from "@/lib/logger";
import OpenAI from "openai";
import { createClient } from "@/lib/supabase/server";
import { checkRateLimit, getClientIP, createRateLimitResponse } from "@/lib/rate-limit";
import { sanitizeInput } from "@/lib/sanitize";
import { withCSRFProtection } from "@/lib/csrf";
import { TRADES } from "@/lib/constants";
import { 
  AI_RATE_LIMIT, 
  AI_WINDOW_MS,
  MAX_LENGTH_TRADE,
  MAX_LENGTH_LOCATION,
  MAX_LENGTH_AVAILABILITY,
  MAX_LENGTH_VOICE_TRANSCRIPT,
  HTTP_STATUS_INTERNAL_SERVER_ERROR 
} from "@/lib/constants";

if (!process.env.OPENAI_API_KEY) {
  throw new Error("OPENAI_API_KEY environment variable is not set");
}

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// Rate limit: 5 requests per 15 minutes per IP (expensive AI call)

const handler = async (request: NextRequest) => {
  try {
    // --- Rate limiting ---
    const clientIP = getClientIP(request);
    const rateLimit = await checkRateLimit(`ai-profile:${clientIP}`, AI_RATE_LIMIT, AI_WINDOW_MS);

    if (!rateLimit.allowed) {
      const retryAfter = Math.ceil((rateLimit.resetTime - Date.now()) / 1000);
      return createRateLimitResponse(clientIP, retryAfter);
    }

    // --- Auth check ---
    const supabase = await createClient();
    const { data: { user }, error: authError } = await supabase.auth.getUser();
    if (authError || !user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { trade, trades, experience, location, availability, voiceTranscript } = await request.json();

    if (!trade || experience === undefined || !location || !availability) {
      return NextResponse.json(
        { error: "Missing required fields" },
        { status: 400 }
      );
    }

    // Sanitize inputs to prevent prompt injection
    const sanitizedTrade = sanitizeInput(trade, { maxLength: MAX_LENGTH_TRADE });
    const sanitizedLocation = sanitizeInput(location, { maxLength: MAX_LENGTH_LOCATION });
    const sanitizedAvailability = sanitizeInput(availability, { maxLength: MAX_LENGTH_AVAILABILITY });
    const sanitizedTranscript = voiceTranscript ? sanitizeInput(voiceTranscript, { maxLength: MAX_LENGTH_VOICE_TRANSCRIPT }) : null;

    // Validate primary trade
    if (!(TRADES as readonly string[]).includes(sanitizedTrade)) {
      return NextResponse.json(
        { error: `Invalid trade. Must be one of: ${TRADES.join(", ")}` },
        { status: 400 }
      );
    }

    // Sanitize and validate additional trades
    const allTrades: string[] = Array.isArray(trades)
      ? trades
          .map((t: string) => sanitizeInput(t, { maxLength: MAX_LENGTH_TRADE }))
          .filter((t: string) => (TRADES as readonly string[]).includes(t))
      : [sanitizedTrade];

    // Ensure at least the primary trade is included
    if (allTrades.length === 0) {
      allTrades.push(sanitizedTrade);
    }

    const tradesStr = allTrades.join(", ");

    // Validate experience is a number
    const experienceYears = parseInt(experience, 10);
    if (isNaN(experienceYears) || experienceYears < 0 || experienceYears > 100) {
      return NextResponse.json(
        { error: "Invalid experience value" },
        { status: 400 }
      );
    }

    const transcriptSection = sanitizedTranscript
      ? `\n\nOriginal voice description from the worker (use this to make the bio personal and unique — reference specific details they mentioned):\n"${sanitizedTranscript}"`
      : "";

    const prompt = `You are an expert construction industry recruiter writing a profile for an Australian construction worker.

Worker Information:
- Trade(s): ${tradesStr}
- Years of Experience: ${experienceYears} years
- Location: ${sanitizedLocation}
- Availability: ${sanitizedAvailability}${transcriptSection}

Generate a JSON response with:
1. bio: A professional 2-3 sentence bio (50-80 words) written in FIRST PERSON ("I", "my", "me"). It's the worker's own bio on their profile. Make it unique — if voice details are provided, incorporate specific things they mentioned (multiple trades, specialties, work style). Do NOT use third person ("they", "their", "them").
2. skills: An array of 6-10 relevant technical skills for their trade(s) (specific tools, techniques, materials). If multiple trades, include skills from each.
3. certifications: An array of 3-5 common/recommended certifications for their trade(s) (actual Australian construction certifications)

Make it sound professional but approachable. Focus on practical skills and experience.

Return ONLY valid JSON in this exact format:
{
  "bio": "string",
  "skills": ["skill1", "skill2", ...],
  "certifications": ["cert1", "cert2", ...]
}`;

    const completion = await openai.chat.completions.create({
      model: "gpt-4o-mini",
      messages: [
        {
          role: "system",
          content: "You are a construction industry expert. Always respond with valid JSON only.",
        },
        {
          role: "user",
          content: prompt,
        },
      ],
      temperature: 0.7,
      response_format: { type: "json_object" },
    });

    const content = completion.choices[0]?.message?.content;
    if (!content) {
      throw new Error("No response from AI");
    }

    const generated = JSON.parse(content);

    return NextResponse.json({
      bio: generated.bio || "",
      skills: generated.skills || [],
      certifications: generated.certifications || [],
    });
  } catch (error) {
    logger.error("AI generation error:", error);

    // Return more specific error messages
    if (error instanceof Error) {
      if (error.message.includes("API key")) {
        return NextResponse.json(
          { error: "AI service configuration error" },
          { status: 503 }
        );
      }
      if (error.message.includes("rate limit") || error.message.includes("429")) {
        return NextResponse.json(
          { error: "AI service is busy. Please try again in a moment." },
          { status: 429 }
        );
      }
    }

    return NextResponse.json(
      { error: "Failed to generate profile. Please try again." },
      { status: 500 }
    );
  }
}

// Apply CSRF protection to the handler
export const POST = withCSRFProtection(handler);
