// managed-bot-webhook
// Recebe updates do @mika_managerbot. Quando o update tem o campo "managed_bot",
// busca o token do novo bot via getManagedBotToken, salva no Vault, atualiza
// o agent_instance correspondente e dispara provisionamento automático.
//
// Setup do webhook: GET ?setup=true configura o webhook do manager bot.
//
// IMPORTANTE: Esta função usa endpoints experimentais do BotFather Bot
// Management Mode que NÃO são parte da Bot API pública oficial.

import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";

function ack(): Response {
  // Sempre 200 — Telegram não deve retentar.
  return new Response("ok", { status: 200 });
}

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

Deno.serve(async (req) => {
  const url = new URL(req.url);
  const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
  const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
  const managerToken = Deno.env.get("TELEGRAM_MANAGER_BOT_TOKEN");

  // Setup: configura webhook
  if (url.searchParams.get("setup") === "true") {
    if (!managerToken) {
      return json({ error: "TELEGRAM_MANAGER_BOT_TOKEN não configurado" }, 400);
    }
    const webhookUrl = `${supabaseUrl}/functions/v1/managed-bot-webhook`;
    const res = await fetch(
      `https://api.telegram.org/bot${managerToken}/setWebhook`,
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          url: webhookUrl,
          allowed_updates: ["message", "managed_bot"],
        }),
      },
    );
    const data = await res.json().catch(() => ({}));
    return json({ webhook_set: webhookUrl, telegram_response: data });
  }

  if (req.method !== "POST") {
    return ack();
  }

  if (!managerToken) {
    console.error("TELEGRAM_MANAGER_BOT_TOKEN ausente");
    return ack();
  }

  let update: Record<string, unknown>;
  try {
    update = await req.json();
  } catch {
    return ack();
  }

  // Só processamos eventos de managed_bot
  // deno-lint-ignore no-explicit-any
  const managed = (update as any).managed_bot;
  if (!managed || !managed.bot) {
    return ack();
  }

  try {
    const admin = createClient(supabaseUrl, serviceKey);

    const botId = managed.bot.id;
    const botUsername: string = managed.bot.username;
    // deno-lint-ignore no-explicit-any
    const tgUser = (managed as any).user ?? {};

    // 1) Busca token do bot recém-criado
    const tokenRes = await fetch(
      `https://api.telegram.org/bot${managerToken}/getManagedBotToken`,
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ bot_id: botId }),
      },
    );
    const tokenJson = await tokenRes.json().catch(() => ({}));
    // deno-lint-ignore no-explicit-any
    const newBotToken: string | undefined = (tokenJson as any)?.result?.token;
    if (!newBotToken) {
      console.error("getManagedBotToken falhou", tokenJson);
      return ack();
    }

    // 2) Localiza agent_instance pendente correspondente
    const filter = tgUser?.id
      ? `telegram_user_chat_id.eq.${tgUser.id},managed_bot_suggested_username.eq.${botUsername}`
      : `managed_bot_suggested_username.eq.${botUsername}`;

    const { data: agentInstance, error: lookupErr } = await admin
      .from("agent_instances")
      .select("id, user_id")
      .eq("managed_bot_pending", true)
      .or(filter)
      .order("created_at", { ascending: false })
      .limit(1)
      .maybeSingle();

    if (lookupErr || !agentInstance) {
      console.error(
        "Nenhum agent_instance pendente encontrado para managed bot",
        { botUsername, tgUserId: tgUser?.id, lookupErr },
      );
      return ack();
    }

    // 3) Salva token no Vault (reutiliza vault_create_secret)
    const secretName = `telegram_bot_token_${agentInstance.id}_${Math.floor(
      Date.now() / 1000,
    )}`;
    const { data: vaultData, error: vaultErr } = await admin
      .rpc("vault_create_secret", {
        secret_value: newBotToken,
        secret_name: secretName,
        secret_description: `Managed bot token for agent ${agentInstance.id}`,
      })
      .single();

    if (vaultErr || !vaultData) {
      console.error("vault_create_secret falhou", vaultErr);
      return ack();
    }
    // deno-lint-ignore no-explicit-any
    const secretId = (vaultData as any).secret_id ?? vaultData;

    // 4) Atualiza agent_instance
    const { error: updErr } = await admin
      .from("agent_instances")
      .update({
        telegram_bot_token_vault_id: secretId,
        telegram_bot_username: botUsername,
        telegram_user_chat_id: tgUser?.id ? Number(tgUser.id) : null,
        telegram_connected_at: new Date().toISOString(),
        telegram_onboarding_completed: true,
        telegram_token_invalid: false,
        managed_bot_pending: false,
        onboarding_completed: true,
        updated_at: new Date().toISOString(),
      })
      .eq("id", agentInstance.id);

    if (updErr) {
      console.error("agent update falhou", updErr);
      return ack();
    }

    // 5) Dispara provisionamento (fire-and-forget)
    fetch(`${supabaseUrl}/functions/v1/provision-agent`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${serviceKey}`,
      },
      body: JSON.stringify({
        agent_instance_id: agentInstance.id,
        user_id: agentInstance.user_id,
      }),
    }).catch((err) => console.error("Auto-provision error:", err));

    return ack();
  } catch (err) {
    console.error("managed-bot-webhook fatal", err);
    return ack();
  }
});
