import { getCachedJson, setCachedJson, mget, hashString } from './_upstash-cache.js';
import { getCorsHeaders, isDisallowedOrigin } from './_cors.js';

export const config = {
  runtime: 'edge',
};

const GROQ_API_URL = 'https://api.groq.com/openai/v1/chat/completions';
const MODEL = 'llama-3.1-8b-instant';
const CACHE_TTL_SECONDS = 86400;
const CACHE_VERSION = 'v1';
const MAX_BATCH_SIZE = 20;

const VALID_LEVELS = ['critical', 'high', 'medium', 'low', 'info'];
const VALID_CATEGORIES = [
  'conflict', 'protest', 'disaster', 'diplomatic', 'economic',
  'terrorism', 'cyber', 'health', 'environmental', 'military',
  'crime', 'infrastructure', 'tech', 'general',
];

export default async function handler(request) {
  const corsHeaders = getCorsHeaders(request, 'POST, OPTIONS');

  if (request.method === 'OPTIONS') {
    return new Response(null, { status: 204, headers: corsHeaders });
  }

  if (request.method !== 'POST') {
    return new Response(JSON.stringify({ error: 'Method not allowed' }), {
      status: 405,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
    });
  }

  if (isDisallowedOrigin(request)) {
    return new Response(JSON.stringify({ error: 'Origin not allowed' }), {
      status: 403,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  const apiKey = process.env.GROQ_API_KEY;
  if (!apiKey) {
    return new Response(JSON.stringify({ results: [], fallback: true, skipped: true, reason: 'GROQ_API_KEY not configured' }), {
      status: 200,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  const contentLength = parseInt(request.headers.get('content-length') || '0', 10);
  if (contentLength > 51200) {
    return new Response(JSON.stringify({ error: 'Payload too large' }), {
      status: 413,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
    });
  }

  let body;
  try {
    body = await request.json();
  } catch {
    return new Response(JSON.stringify({ error: 'Invalid JSON body' }), {
      status: 400,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  const { titles, variant = 'full' } = body;
  if (!Array.isArray(titles) || titles.length === 0) {
    return new Response(JSON.stringify({ error: 'titles array required' }), {
      status: 400,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  const batch = titles.slice(0, MAX_BATCH_SIZE);
  const results = new Array(batch.length).fill(null);
  const uncachedIndices = [];

  const cacheKeys = batch.map(
    (t) => `classify:${CACHE_VERSION}:${hashString(t.toLowerCase() + ':' + variant)}`
  );
  const cached = await mget(...cacheKeys);
  for (let i = 0; i < cached.length; i++) {
    const val = cached[i];
    if (val && typeof val === 'object' && val.level) {
      results[i] = { level: val.level, category: val.category, cached: true };
    } else {
      uncachedIndices.push(i);
    }
  }

  if (uncachedIndices.length === 0) {
    return new Response(JSON.stringify({ results }), {
      status: 200,
      headers: { 'Content-Type': 'application/json', 'Cache-Control': 'public, max-age=3600, s-maxage=3600, stale-while-revalidate=600' },
    });
  }

  const uncachedTitles = uncachedIndices.map((i) => batch[i]);
  const isTech = variant === 'tech';
  const numberedList = uncachedTitles.map((t, i) => `${i + 1}. ${t}`).join('\n');

  const systemPrompt = `You classify news headlines into threat level and category. Return ONLY a valid JSON array, no other text.

Levels: critical, high, medium, low, info
Categories: conflict, protest, disaster, diplomatic, economic, terrorism, cyber, health, environmental, military, crime, infrastructure, tech, general

${isTech ? 'Focus: technology, startups, AI, cybersecurity. Most tech news is "low" or "info" unless it involves outages, breaches, or major disruptions.' : 'Focus: geopolitical events, conflicts, disasters, diplomacy. Classify by real-world severity and impact.'}

Return a JSON array with one object per headline in order: [{"level":"...","category":"..."},...]`;

  try {
    const response = await fetch(GROQ_API_URL, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        model: MODEL,
        messages: [
          { role: 'system', content: systemPrompt },
          { role: 'user', content: numberedList },
        ],
        temperature: 0,
        max_tokens: uncachedTitles.length * 60,
      }),
    });

    if (!response.ok) {
      console.error('[ClassifyBatch] Groq error:', response.status);
      return new Response(JSON.stringify({ results, fallback: true }), {
        status: response.status,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    const data = await response.json();
    const raw = data.choices?.[0]?.message?.content?.trim();
    if (!raw) {
      return new Response(JSON.stringify({ results, fallback: true }), {
        status: 200,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    let parsed;
    try {
      parsed = JSON.parse(raw);
    } catch {
      const match = raw.match(/\[[\s\S]*\]/);
      if (match) {
        try { parsed = JSON.parse(match[0]); } catch { /* fall through */ }
      }
    }

    if (!Array.isArray(parsed)) {
      return new Response(JSON.stringify({ results, fallback: true }), {
        status: 200,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    const cacheWrites = [];
    for (let i = 0; i < uncachedIndices.length; i++) {
      const classification = parsed[i];
      if (!classification) continue;

      const level = VALID_LEVELS.includes(classification.level) ? classification.level : null;
      const category = VALID_CATEGORIES.includes(classification.category) ? classification.category : null;
      if (!level || !category) continue;

      const idx = uncachedIndices[i];
      results[idx] = { level, category, cached: false };

      const cacheKey = `classify:${CACHE_VERSION}:${hashString(batch[idx].toLowerCase() + ':' + variant)}`;
      cacheWrites.push(
        setCachedJson(cacheKey, { level, category, timestamp: Date.now() }, CACHE_TTL_SECONDS)
      );
    }

    if (cacheWrites.length > 0) {
      await Promise.allSettled(cacheWrites);
    }

    return new Response(JSON.stringify({ results }), {
      status: 200,
      headers: { 'Content-Type': 'application/json', 'Cache-Control': 'public, max-age=3600, s-maxage=3600, stale-while-revalidate=600' },
    });
  } catch (error) {
    console.error('[ClassifyBatch] Error:', error.message);
    return new Response(JSON.stringify({ results, fallback: true }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
}
