// Edge Function: importar-menu-ia
// Recibe la foto de un menu, usa Gemini (vision) para extraer productos estructurados.
// Valida que el llamador sea dueno/staff via los endpoints internos de Supabase
// (sin dependencias externas: evita el import por CDN que falla por IPv6 en Docker local).
// La API key de Gemini vive solo en el servidor.

const CORS = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
  'Access-Control-Allow-Methods': 'POST, OPTIONS',
};

function json(obj: unknown, status = 200) {
  return new Response(JSON.stringify(obj), {
    status,
    headers: { ...CORS, 'Content-Type': 'application/json' },
  });
}

const PROMPT = `Eres un asistente que digitaliza menus de restaurantes en Venezuela.
Analiza la imagen del menu y extrae los productos.
Devuelve SOLO JSON valido con esta forma exacta:
{"categorias":["Nombre"],"productos":[{"nombre":"...","descripcion":"...","precio_usd":0,"categoria":"Nombre"}]}
Reglas:
- precio_usd es un numero en dolares. Si el precio esta en bolivares o no se ve, pon 0.
- "categoria" de cada producto debe coincidir con una de la lista "categorias".
- descripcion es opcional (cadena vacia si no hay).
- No inventes productos que no aparezcan en la imagen.`;

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') return new Response('ok', { headers: CORS });
  if (req.method !== 'POST') return json({ error: 'Metodo no permitido' }, 405);

  try {
    const SUPABASE_URL = Deno.env.get('SUPABASE_URL')!;
    const ANON = Deno.env.get('SUPABASE_ANON_KEY')!;
    const authHeader = req.headers.get('Authorization');
    if (!authHeader) return json({ error: 'No autorizado' }, 401);

    // 1) Validar la sesion (GoTrue interno)
    const uRes = await fetch(`${SUPABASE_URL}/auth/v1/user`, {
      headers: { Authorization: authHeader, apikey: ANON },
    });
    if (!uRes.ok) return json({ error: 'Sesion invalida' }, 401);
    const user = (await uRes.json()) as { id?: string };
    if (!user?.id) return json({ error: 'Sesion invalida' }, 401);

    // 2) Validar el rol (PostgREST interno; RLS deja al usuario leer su propio perfil)
    const pRes = await fetch(
      `${SUPABASE_URL}/rest/v1/perfiles?id=eq.${user.id}&select=rol`,
      { headers: { Authorization: authHeader, apikey: ANON } },
    );
    const perfiles = pRes.ok ? ((await pRes.json()) as { rol?: string }[]) : [];
    const rol = perfiles?.[0]?.rol;
    if (!rol || !['dueno', 'staff', 'admin'].includes(rol)) {
      return json({ error: 'Solo el dueno puede importar el menu' }, 403);
    }

    // 3) Leer la imagen
    const { imagen_base64, mime_type } = await req.json();
    if (!imagen_base64) return json({ error: 'Falta la imagen' }, 400);

    const KEY = Deno.env.get('GEMINI_API_KEY');
    if (!KEY) return json({ error: 'Falta configurar GEMINI_API_KEY en el servidor' }, 500);
    const MODEL = Deno.env.get('GEMINI_MODEL') ?? 'gemini-2.5-flash';

    // 4) Llamar a Gemini (vision -> JSON)
    const body = {
      contents: [
        {
          parts: [
            { inline_data: { mime_type: mime_type ?? 'image/jpeg', data: imagen_base64 } },
            { text: PROMPT },
          ],
        },
      ],
      generationConfig: { responseMimeType: 'application/json' },
    };

    const r = await fetch(
      `https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent`,
      {
        method: 'POST',
        headers: { 'x-goog-api-key': KEY, 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      },
    );
    if (!r.ok) {
      const t = await r.text();
      return json({ error: 'La IA no pudo procesar la imagen', detalle: t.slice(0, 200) }, 502);
    }
    const j = await r.json();
    const txt = j?.candidates?.[0]?.content?.parts?.[0]?.text;
    if (!txt) return json({ error: 'La IA no devolvio resultados' }, 502);

    let parsed: { categorias?: unknown; productos?: unknown };
    try {
      parsed = JSON.parse(txt);
    } catch {
      return json({ error: 'La IA devolvio un formato invalido' }, 502);
    }

    const categorias = Array.isArray(parsed.categorias)
      ? (parsed.categorias as unknown[]).filter((c): c is string => typeof c === 'string')
      : [];
    const productos = Array.isArray(parsed.productos)
      ? (parsed.productos as Record<string, unknown>[])
          .map((p) => ({
            nombre: String(p.nombre ?? '').slice(0, 120),
            descripcion: p.descripcion ? String(p.descripcion).slice(0, 300) : null,
            precio_usd: Number(p.precio_usd) || 0,
            categoria: p.categoria ? String(p.categoria) : null,
          }))
          .filter((p) => p.nombre.length > 0)
      : [];

    return json({ categorias, productos });
  } catch (e) {
    return json({ error: 'Error inesperado', detalle: String(e) }, 500);
  }
});
