// capture-telegram-owner
// Após o cliente conectar o bot (validate-telegram-bot), pedimos a ele que
// envie /start ao próprio bot. Esta função faz polling no getUpdates do
// bot do cliente para descobrir o chat_id do dono. Quando encontra:
//   1) grava telegram_user_chat_id em agent_instances
//   2) envia mensagem de confirmação ao usuário
//   3) limpa o offset (markAsRead) chamando getUpdates com offset alto
//   4) se o agente já está provisionado no Railway, atualiza as env vars
//      TELEGRAM_ALLOWED_USERS / TELEGRAM_HOME_CHANNEL e dispara redeploy
//
// É chamada repetidamente pelo frontend (poll a cada 2s) até retornar
// { found: true } ou o usuário desistir.

import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
import { corsHeaders } from "../_shared/cors.ts";
import { telegramApi } from "../_shared/telegram.ts";
import {
  deployRailwayService,
  getServiceContext,
  upsertRailwayVariableCollection,
} from "../_shared/railway.ts";

const RAILWAY_API_TOKEN = Deno.env.get("RAILWAY_API_TOKEN");

interface TelegramUpdate {
  update_id: number;
  message?: {
    chat?: { id: number; type?: string };
    from?: { id: number; is_bot?: boolean; username?: string; first_name?: string };
    text?: string;
  };
}

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

Deno.serve(async (req) => {
  if (req.method === "OPTIONS") {
    return new Response(null, { headers: corsHeaders });
  }

  try {
    const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
    const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
    const anonKey = Deno.env.get("SUPABASE_ANON_KEY")!;

    const authHeader = req.headers.get("Authorization") ?? "";
    const userClient = createClient(supabaseUrl, anonKey, {
      global: { headers: { Authorization: authHeader } },
    });
    const { data: userData, error: userErr } = await userClient.auth.getUser();
    if (userErr || !userData.user) {
      return jsonResponse({ error: "Não autenticado" }, 401);
    }
    const userId = userData.user.id;

    const admin = createClient(supabaseUrl, serviceKey);

    // 1) Carrega agent + token do Vault
    const { data: agent, error: agentErr } = await admin
      .from("agent_instances")
      .select(
        "id, status, telegram_bot_token_vault_id, telegram_bot_username, telegram_user_chat_id, railway_service_id, vps_pool_id",
      )
      .eq("user_id", userId)
      .maybeSingle();

    if (agentErr || !agent) {
      return jsonResponse({ error: "Agente não encontrado." }, 404);
    }

    // Já capturado anteriormente — short-circuit
    if (agent.telegram_user_chat_id) {
      return jsonResponse({
        found: true,
        chat_id: Number(agent.telegram_user_chat_id),
        bot_username: agent.telegram_bot_username,
        already_captured: true,
      });
    }

    if (!agent.telegram_bot_token_vault_id) {
      return jsonResponse(
        { error: "Bot ainda não conectado. Volte e cole o token do BotFather." },
        409,
      );
    }

    const { data: secret } = await admin.rpc("vault_decrypt_secret", {
      secret_id: agent.telegram_bot_token_vault_id,
    });
    // deno-lint-ignore no-explicit-any
    const token: string = (secret?.[0] as any)?.decrypted_secret ?? "";
    if (!token) {
      return jsonResponse({ error: "Falha ao decifrar token." }, 500);
    }

    // 2) Garante que o webhook está deletado (senão getUpdates falha)
    await telegramApi(token, "deleteWebhook", { drop_pending_updates: false });

    // 3) Faz getUpdates com timeout curto (long polling 8s) — pega TODAS as mensagens recentes
    const updRes = await telegramApi<TelegramUpdate[]>(token, "getUpdates", {
      timeout: 8,
      allowed_updates: ["message"],
    });

    if (!updRes.ok) {
      console.error("getUpdates failed", updRes);
      return jsonResponse(
        { error: updRes.description || "Falha ao consultar Telegram." },
        502,
      );
    }

    const updates = updRes.result ?? [];

    // 4) Procura a primeira mensagem privada de um humano
    let ownerChatId: number | null = null;
    let ownerUsername: string | null = null;
    let ownerFirstName: string | null = null;
    let highestUpdateId = 0;

    for (const u of updates) {
      if (u.update_id > highestUpdateId) highestUpdateId = u.update_id;
      const msg = u.message;
      if (!msg) continue;
      const chat = msg.chat;
      const from = msg.from;
      if (!chat || !from || from.is_bot) continue;
      // Só aceita chat privado (chat.id === from.id em DMs)
      if (chat.type && chat.type !== "private") continue;

      ownerChatId = chat.id;
      ownerUsername = from.username ?? null;
      ownerFirstName = from.first_name ?? null;
      break;
    }

    // 5) Avança o offset para "consumir" os updates lidos (mesmo se não achou,
    // limpa lixo antigo). Usar offset = highest+1.
    if (highestUpdateId > 0) {
      await telegramApi(token, "getUpdates", {
        offset: highestUpdateId + 1,
        timeout: 0,
        limit: 1,
      });
    }

    if (!ownerChatId) {
      return jsonResponse({
        found: false,
        bot_username: agent.telegram_bot_username,
        hint: "Envie /start no Telegram ao seu bot para identificá-lo.",
      });
    }

    // 6) Persiste chat_id
    await admin
      .from("agent_instances")
      .update({
        telegram_user_chat_id: ownerChatId,
        telegram_first_message_received_at: new Date().toISOString(),
        updated_at: new Date().toISOString(),
      })
      .eq("id", agent.id);

    // 7) Mensagem de confirmação imediata (é o último "ping" antes do Hermes assumir)
    await telegramApi(token, "sendMessage", {
      chat_id: ownerChatId,
      text:
        `✅ Tudo certo${ownerFirstName ? `, ${ownerFirstName}` : ""}! Seu agente está sendo ativado e em alguns instantes começa a conversar com você por aqui. ✨`,
    });

    // 8) Se já existe serviço Railway, atualiza TELEGRAM_ALLOWED_USERS / HOME_CHANNEL e redeploy
    let redeployed = false;
    if (agent.railway_service_id && RAILWAY_API_TOKEN) {
      try {
        let projectId: string | null = null;
        let environmentId: string | null = null;
        if (agent.vps_pool_id) {
          const { data: pool } = await admin
            .from("vps_pool")
            .select("railway_project_id, railway_environment_id")
            .eq("id", agent.vps_pool_id)
            .maybeSingle();
          projectId = pool?.railway_project_id ?? null;
          environmentId = pool?.railway_environment_id ?? null;
        }
        if (!projectId || !environmentId) {
          const ctx = await getServiceContext({
            token: RAILWAY_API_TOKEN,
            serviceId: agent.railway_service_id,
          });
          projectId = projectId ?? ctx.projectId;
          environmentId = environmentId ?? ctx.environmentId;
        }
        if (projectId && environmentId) {
          const chatIdStr = String(ownerChatId);
          await upsertRailwayVariableCollection({
            token: RAILWAY_API_TOKEN,
            serviceId: agent.railway_service_id,
            environmentId,
            projectId,
            variables: {
              TELEGRAM_ALLOWED_USERS: chatIdStr,
              TELEGRAM_HOME_CHANNEL: chatIdStr,
            },
            skipDeploys: true,
          });
          await deployRailwayService({
            token: RAILWAY_API_TOKEN,
            serviceId: agent.railway_service_id,
            environmentId,
          });
          redeployed = true;
          console.log(
            `[capture-telegram-owner] Railway redeploy disparado para serviço ${agent.railway_service_id}`,
          );
        }
      } catch (e) {
        console.error(
          "[capture-telegram-owner] falha ao atualizar Railway:",
          e instanceof Error ? e.message : String(e),
        );
      }
    }

    return jsonResponse({
      found: true,
      chat_id: ownerChatId,
      username: ownerUsername,
      first_name: ownerFirstName,
      bot_username: agent.telegram_bot_username,
      redeployed,
    });
  } catch (err) {
    console.error("capture-telegram-owner fatal", err);
    return jsonResponse(
      { error: err instanceof Error ? err.message : "Erro inesperado" },
      500,
    );
  }
});
