// Edge Function: gestionar-mesero
// El dueño administra su equipo (usuario auth + perfil de SU restaurante) y
// lo elimina (borra el usuario auth; los pedidos historicos conservan
// mesero_nombre porque es un snapshot). Dos roles posibles: 'staff' (mesero,
// solo opera su sala) y 'encargado' (opera el negocio pero sin lo gerencial).
// Valida al llamador internamente (sin imports por CDN, igual que crear-repartidor).

const ROLES_VALIDOS = ['staff', 'encargado'];

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 SERVICE = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
    const svc = { apikey: SERVICE, Authorization: `Bearer ${SERVICE}` };

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

    // 1) Validar la sesion del llamador.
    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) El llamador debe ser dueño con restaurante.
    const pRes = await fetch(
      `${SUPABASE_URL}/rest/v1/perfiles?id=eq.${user.id}&select=rol,restaurante_id`,
      { headers: svc },
    );
    const perfiles = pRes.ok ? ((await pRes.json()) as { rol?: string; restaurante_id?: string }[]) : [];
    const dueno = perfiles?.[0];
    if (!dueno || dueno.rol !== 'dueno' || !dueno.restaurante_id) {
      return json({ error: 'Solo el dueño del negocio puede administrar meseros.' }, 403);
    }
    const restauranteId = dueno.restaurante_id;

    const body = (await req.json()) as Record<string, unknown>;
    const accion = String(body.accion ?? 'crear');

    // ---- Eliminar mesero/encargado: solo si es del equipo DE ESTE restaurante ----
    if (accion === 'eliminar') {
      const meseroId = String(body.mesero_id ?? '').trim();
      if (!meseroId) return json({ error: 'Falta el mesero a eliminar.' }, 400);
      const tRes = await fetch(
        `${SUPABASE_URL}/rest/v1/perfiles?id=eq.${meseroId}&select=id,rol,restaurante_id`,
        { headers: svc },
      );
      const target = (tRes.ok ? ((await tRes.json()) as { rol?: string; restaurante_id?: string }[]) : [])?.[0];
      if (!target || !ROLES_VALIDOS.includes(target.rol ?? '') || target.restaurante_id !== restauranteId) {
        return json({ error: 'Ese mesero no pertenece a tu negocio.' }, 403);
      }
      const dRes = await fetch(`${SUPABASE_URL}/auth/v1/admin/users/${meseroId}`, {
        method: 'DELETE',
        headers: svc,
      });
      if (!dRes.ok) {
        const t = await dRes.text();
        return json({ error: 'No se pudo eliminar: ' + t.slice(0, 150) }, 400);
      }
      return json({ ok: true });
    }

    // Helper: valida que el objetivo sea mesero o encargado DE ESTE restaurante.
    const meseroDeMiNegocio = async (meseroId: string): Promise<boolean> => {
      if (!meseroId) return false;
      const tRes = await fetch(
        `${SUPABASE_URL}/rest/v1/perfiles?id=eq.${meseroId}&select=rol,restaurante_id`,
        { headers: svc },
      );
      const target = (tRes.ok ? ((await tRes.json()) as { rol?: string; restaurante_id?: string }[]) : [])?.[0];
      return !!target && ROLES_VALIDOS.includes(target.rol ?? '') && target.restaurante_id === restauranteId;
    };

    // ---- Editar mesero (nombre / telefono) ----
    if (accion === 'editar') {
      const meseroId = String(body.mesero_id ?? '').trim();
      const nombre = String(body.nombre ?? '').trim();
      if (!nombre) return json({ error: 'Falta el nombre.' }, 400);
      if (!(await meseroDeMiNegocio(meseroId))) return json({ error: 'Ese mesero no pertenece a tu negocio.' }, 403);
      const upRes = await fetch(`${SUPABASE_URL}/rest/v1/perfiles?id=eq.${meseroId}`, {
        method: 'PATCH',
        headers: { ...svc, 'Content-Type': 'application/json', Prefer: 'return=minimal' },
        body: JSON.stringify({ nombre, telefono: body.telefono ? String(body.telefono).trim() : null }),
      });
      if (!upRes.ok) return json({ error: 'No se pudo editar: ' + (await upRes.text()).slice(0, 150) }, 400);
      return json({ ok: true });
    }

    // ---- Resetear la clave de un mesero ----
    if (accion === 'resetear_clave') {
      const meseroId = String(body.mesero_id ?? '').trim();
      const password = String(body.password ?? '');
      if (password.length < 6) return json({ error: 'La clave debe tener al menos 6 caracteres.' }, 400);
      if (!(await meseroDeMiNegocio(meseroId))) return json({ error: 'Ese mesero no pertenece a tu negocio.' }, 403);
      const rRes = await fetch(`${SUPABASE_URL}/auth/v1/admin/users/${meseroId}`, {
        method: 'PUT',
        headers: { ...svc, 'Content-Type': 'application/json' },
        body: JSON.stringify({ password }),
      });
      if (!rRes.ok) return json({ error: 'No se pudo cambiar la clave: ' + (await rRes.text()).slice(0, 150) }, 400);
      return json({ ok: true });
    }

    if (accion !== 'crear') return json({ error: 'Accion invalida' }, 400);

    // ---- Crear mesero o encargado ----
    const { nombre, email, password, telefono, rol } = body as {
      nombre?: string; email?: string; password?: string; telefono?: string; rol?: string;
    };
    const correo = String(email ?? '').trim().toLowerCase();
    const rolNuevo = ROLES_VALIDOS.includes(String(rol)) ? String(rol) : 'staff';
    if (!nombre || !String(nombre).trim() || !correo || !password || String(password).length < 6) {
      return json({ error: 'Faltan datos: nombre, correo y clave de al menos 6 caracteres.' }, 400);
    }

    // 3) Invitar por correo: crea la cuenta y le envia el link de activacion.
    const cRes = await fetch(`${SUPABASE_URL}/auth/v1/invite`, {
      method: 'POST',
      headers: { ...svc, 'Content-Type': 'application/json' },
      body: JSON.stringify({ email: correo, data: { nombre } }),
    });
    if (!cRes.ok) {
      const e = (await cRes.json().catch(() => ({}))) as Record<string, unknown>;
      const m = String(e?.msg ?? e?.message ?? e?.error_description ?? 'No se pudo crear el usuario');
      return json({ error: /already|registered|exists/i.test(m) ? 'Ese correo ya esta registrado.' : m }, 400);
    }
    const nuevo = (await cRes.json()) as { id?: string; user?: { id?: string } };
    const nuevoId = nuevo.id ?? nuevo.user?.id;
    if (!nuevoId) return json({ error: 'No se obtuvo el id del nuevo usuario' }, 500);

    // 3b) Ponerle la clave que eligio el negocio y confirmar la cuenta, para que la
    //     clave sirva de una (ademas del link de activacion que ya se envio al correo).
    await fetch(`${SUPABASE_URL}/auth/v1/admin/users/${nuevoId}`, {
      method: 'PUT',
      headers: { ...svc, 'Content-Type': 'application/json' },
      body: JSON.stringify({ password, email_confirm: true }),
    });

    // 4) Perfil -> mesero del restaurante (upsert por si el trigger ya creo el perfil).
    const upRes = await fetch(`${SUPABASE_URL}/rest/v1/perfiles?on_conflict=id`, {
      method: 'POST',
      headers: { ...svc, 'Content-Type': 'application/json', Prefer: 'resolution=merge-duplicates,return=minimal' },
      body: JSON.stringify({
        id: nuevoId,
        rol: rolNuevo,
        restaurante_id: restauranteId,
        nombre: String(nombre).trim(),
        telefono: telefono || null,
      }),
    });
    if (!upRes.ok) {
      const t = await upRes.text();
      return json({ error: 'No se pudo configurar el perfil: ' + t.slice(0, 150) }, 400);
    }

    return json({ ok: true, mesero_id: nuevoId });
  } catch (e) {
    return json({ error: 'Error inesperado', detalle: String(e) }, 500);
  }
});
