// Edge Function: cerebro-receta (Cerebro de costos, v1.1)
// Entrevista al dueno COMO HABLA y arma la receta del plato COMPLETO:
//   - la BASE (lo que siempre lleva: masa, pan, empaque) con opcion = ''
//   - CADA OPCION de los grupos del producto (proteinas, contornos) con
//     opcion = nombre exacto de la opcion (ej 'Mechada').
// El caso real: la Arepa Completa a $5 con "elige 2 proteinas y 3 contornos";
// el costo de verdad esta en las opciones, no en la arepa cruda.
// Devuelve SIEMPRE JSON: { listo:false, pregunta } o { listo:true, receta }.
// Tras entregar receta, el dueno puede seguir pidiendo ajustes: se responde
// con la receta COMPLETA corregida.

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' },
  });
}

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);

    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);

    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', 'encargado', 'admin'].includes(rol)) {
      return json({ error: 'Solo el dueno o el encargado arman recetas' }, 403);
    }

    const { producto, grupos, ingredientes, mensajes } = (await req.json()) as {
      producto?: { nombre?: string; descripcion?: string };
      grupos?: { nombre: string; max?: number | null; opciones: string[] }[];
      ingredientes?: { id: string; nombre: string; unidad_base: string }[];
      mensajes?: { de: 'dueno' | 'ia'; texto: string }[];
    };
    if (!producto?.nombre) return json({ error: 'Falta el producto' }, 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';

    const listaIng = (ingredientes ?? [])
      .map((i) => `- id=${i.id} | ${i.nombre} | unidad=${i.unidad_base}`)
      .join('\n');

    const listaGrupos = (grupos ?? [])
      .map((g) => `- Grupo "${g.nombre}" (el cliente elige hasta ${g.max ?? 1}): ${g.opciones.join(', ')}`)
      .join('\n');
    const nombresOpciones = new Set((grupos ?? []).flatMap((g) => g.opciones));

    const SISTEMA = `Eres el contador de cocina criollo de un restaurante VENEZOLANO. Tu mision: la receta COMPLETA del producto "${producto.nombre}"${producto.descripcion ? ` (${producto.descripcion})` : ''} para calcular su costo.
YA TIENES EL MENU CARGADO. Estos son los grupos y opciones REALES del producto (no preguntes que lleva, ni que opciones tiene, ni cuantas se eligen: YA LO SABES):
${listaGrupos || '(este producto no tiene opciones: solo la base)'}
REGLA DE ORO: NO ENTREVISTES. Tu PRIMERA respuesta es SIEMPRE la receta COMPLETA PROPUESTA (listo:true) con porciones tipicas de cocina venezolana, para que el dueno solo corrija lo que no le cuadre:
- La BASE (opcion ""): el componente principal segun el nombre del producto (ej arepa: harina de maiz 60 g por unidad; hamburguesa: pan 1 unidad + carne 120 g; pizza: masa + queso + salsa). Nada de sal/agua/especias baratas.
- CADA OPCION de CADA grupo con su porcion tipica: proteinas guisadas 80-100 g, quesos 50-70 g, contornos (aguacate, tajadas, palmito) 50-70 g, salsas 20-30 ml, toppings chiquitos 10-20 g.
- En "comentario" avisa corto que es una propuesta con porciones tipicas y que corrija lo que sea.
Despues de la propuesta, cada mensaje del dueno es un AJUSTE: devuelve SIEMPRE la receta COMPLETA corregida (listo:true). Solo haz UNA pregunta corta ({"listo":false,"pregunta":"..."}) si lo que pidio es de verdad ambiguo.
Reglas DURAS:
- Convierte TODO a unidad base POR PLATO/PORCION: "g" (solidos), "ml" (liquidos), "unidad" (contables). Si el dueno habla en rendimientos ("1 kg rinde 16"), TU conviertes (63 g).
- Ingredientes que YA existen en el negocio (reusalos con su id si te sirven):
${listaIng || '(ninguno todavia)'}
- Cada renglon lleva "opcion": "" si es de la BASE, o el nombre EXACTO de la opcion del grupo (ej "Mechada").
- Responde SIEMPRE con SOLO JSON valido, sin texto afuera:
  {"listo":true,"comentario":"resumen en 1 linea","receta":[{"opcion":"","ingrediente_id":null,"nombre":"Harina de maiz","unidad_base":"g","cantidad_base":60},{"opcion":"Mechada","ingrediente_id":null,"nombre":"Carne mechada","unidad_base":"g","cantidad_base":90}]}
  o si de verdad hace falta aclarar: {"listo":false,"pregunta":"..."}
- "cantidad_base" es numero POR PLATO/PORCION, mayor que 0.`;

    const contents: { role: string; parts: { text: string }[] }[] = [];
    contents.push({ role: 'user', parts: [{ text: SISTEMA + '\n\nDame la receta propuesta (o aplica los ajustes del historial).' }] });
    for (const m of mensajes ?? []) {
      contents.push({
        role: m.de === 'ia' ? 'model' : 'user',
        parts: [{ text: String(m.texto ?? '').slice(0, 2000) }],
      });
    }

    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({ contents, generationConfig: { responseMimeType: 'application/json' } }),
      },
    );
    if (!r.ok) {
      const t = await r.text();
      return json({ error: 'La IA no respondio', 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: { listo?: unknown; pregunta?: unknown; comentario?: unknown; receta?: unknown };
    try {
      parsed = JSON.parse(txt);
    } catch {
      return json({ error: 'La IA devolvio un formato invalido' }, 502);
    }

    if (!parsed.listo) {
      return json({
        listo: false,
        pregunta: typeof parsed.pregunta === 'string' && parsed.pregunta.trim()
          ? parsed.pregunta.slice(0, 500)
          : `¿Qué lleva ${producto.nombre} y más o menos en qué cantidades?`,
      });
    }

    const idsValidos = new Set((ingredientes ?? []).map((i) => i.id));
    const receta = (Array.isArray(parsed.receta) ? parsed.receta : [])
      .filter((x): x is Record<string, unknown> => !!x && typeof x === 'object')
      .map((x) => ({
        opcion: typeof x.opcion === 'string' && nombresOpciones.has(x.opcion) ? x.opcion : '',
        ingrediente_id: typeof x.ingrediente_id === 'string' && idsValidos.has(x.ingrediente_id) ? x.ingrediente_id : null,
        nombre: typeof x.nombre === 'string' ? x.nombre.slice(0, 80) : '',
        unidad_base: ['g', 'ml', 'unidad'].includes(String(x.unidad_base)) ? String(x.unidad_base) : 'g',
        cantidad_base: Number(x.cantidad_base) > 0 ? Number(x.cantidad_base) : 0,
      }))
      .filter((x) => x.nombre && x.cantidad_base > 0);

    if (!receta.length) {
      return json({ listo: false, pregunta: 'No me quedó clara la receta. ¿Me repites qué lleva el plato y las cantidades aproximadas?' });
    }

    return json({
      listo: true,
      comentario: typeof parsed.comentario === 'string' ? parsed.comentario.slice(0, 300) : '',
      receta,
    });
  } catch (e) {
    return json({ error: 'Error inesperado: ' + (e as Error).message }, 500);
  }
});
