// telegram-webhook (PÚBLICA — verify_jwt = false)
// Recebe updates do Telegram, valida 3 camadas (uuid_tenant, secret, rate limit),
// registra mensagem em telegram_messages_log e responde com placeholder via sendMessage.
//
// TODO Fase 5: substituir resposta placeholder por proxy para container Hermes via SSH/API.

import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
import { telegramApi, telegramAck } from "../_shared/telegram.ts";

const RATE_LIMIT_MAX = 30;
const RATE_LIMIT_WINDOW_MS = 60_000;

function firstName(fullName: string | null | undefined): string {
  if (!fullName) return "Mika";
  const parts = fullName.trim().split(/\s+/);
  return parts[0] || "Mika";
}

async function getDecryptedSecret(
  admin: ReturnType<typeof createClient>,
  secretId: string,
): Promise<string | null> {
  const { data, error } = await admin
    .rpc("vault_decrypt_secret", { secret_id: secretId })
    .single();
  if (!error && data) {
    // deno-lint-ignore no-explicit-any
    return (data as any).decrypted_secret ?? (data as unknown as string);
  }
  return null;
}

Deno.serve(async (req) => {
  // Sempre responde 200 para o Telegram não retentar — ack cedo em qualquer falha.
  try {
    const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
    const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
    const admin = createClient(supabaseUrl, serviceKey);

    const url = new URL(req.url);
    const uuidTenant = url.searchParams.get("token");
    if (!uuidTenant) return telegramAck();

    const incomingSecret = req.headers.get("X-Telegram-Bot-Api-Secret-Token") ?? "";

    // 1) Localiza agente + nome do usuário
    const { data: agent, error: agentErr } = await admin
      .from("agent_instances")
      .select(
        "id, user_id, status, telegram_webhook_secret, telegram_bot_token_vault_id, telegram_connected_at, profiles:profiles!agent_instances_user_id_fkey(full_name)",
      )
      .eq("uuid_tenant", uuidTenant)
      .maybeSingle();

    if (agentErr || !agent) return telegramAck();
    if (agent.status === "suspended" || agent.status === "error") return telegramAck();

    // 2) Valida secret_token (anti-spoofing)
    if (
      !agent.telegram_webhook_secret ||
      incomingSecret !== agent.telegram_webhook_secret
    ) {
      console.warn("telegram-webhook: secret mismatch", { agent_id: agent.id });
      return new Response("unauthorized", { status: 401 });
    }

    // 3) Rate limit por agent_instance (30 req/min)
    const now = new Date();
    const { data: bucket } = await admin
      .from("telegram_rate_limit_bucket")
      .select("*")
      .eq("agent_instance_id", agent.id)
      .maybeSingle();

    if (!bucket) {
      await admin.from("telegram_rate_limit_bucket").insert({
        agent_instance_id: agent.id,
        request_count: 1,
        window_start: now.toISOString(),
        updated_at: now.toISOString(),
      });
    } else {
      const windowStart = new Date(bucket.window_start as string);
      const elapsed = now.getTime() - windowStart.getTime();
      if (elapsed > RATE_LIMIT_WINDOW_MS) {
        await admin
          .from("telegram_rate_limit_bucket")
          .update({
            request_count: 1,
            window_start: now.toISOString(),
            updated_at: now.toISOString(),
          })
          .eq("agent_instance_id", agent.id);
      } else {
        const newCount = (bucket.request_count as number) + 1;
        if (newCount > RATE_LIMIT_MAX) {
          console.warn("telegram-webhook: rate limit hit", { agent_id: agent.id });
          return telegramAck(); // throttle silencioso
        }
        await admin
          .from("telegram_rate_limit_bucket")
          .update({
            request_count: newCount,
            updated_at: now.toISOString(),
          })
          .eq("agent_instance_id", agent.id);
      }
    }

    // 4) Parse do payload
    const payload = await req.json().catch(() => null);
    if (!payload || !payload.message) return telegramAck();

    const message = payload.message;
    const chatId = message.chat?.id as number | undefined;
    if (!chatId) return telegramAck();

    const fromId = message.from?.id as number | null | undefined;
    const fromUsername = (message.from?.username as string | undefined) ?? null;
    const text = (message.text as string | undefined) ?? null;
    const entities = (message.entities as Array<{ type: string }> | undefined) ?? [];

    let messageType: "text" | "command" | "other" = "other";
    if (entities.some((e) => e.type === "bot_command")) messageType = "command";
    else if (text) messageType = "text";

    // 5) Detecta primeira mensagem da sessão atual
    let isFirstMessage = false;
    if (agent.telegram_connected_at) {
      const { count } = await admin
        .from("telegram_messages_log")
        .select("id", { count: "exact", head: true })
        .eq("agent_instance_id", agent.id)
        .eq("direction", "incoming")
        .gte("created_at", agent.telegram_connected_at as string);
      if ((count ?? 0) === 0) {
        isFirstMessage = true;
        await admin
          .from("agent_instances")
          .update({ telegram_first_message_received_at: now.toISOString() })
          .eq("id", agent.id);
      }
    }

    // 6) Insert da mensagem incoming
    await admin.from("telegram_messages_log").insert({
      agent_instance_id: agent.id,
      user_id: agent.user_id,
      telegram_chat_id: chatId,
      telegram_user_id: fromId ?? null,
      telegram_username: fromUsername,
      direction: "incoming",
      message_text: text,
      message_type: messageType,
      is_first_message: isFirstMessage,
      raw_payload: payload,
    });

    // 7) Resposta placeholder via sendMessage
    // TODO Fase 5: substituir resposta placeholder por proxy para container Hermes via SSH/API.
    if (!agent.telegram_bot_token_vault_id) return telegramAck();
    const token = await getDecryptedSecret(admin, agent.telegram_bot_token_vault_id as string);
    if (!token) return telegramAck();

    // deno-lint-ignore no-explicit-any
    const fullName = (agent as any).profiles?.full_name as string | null | undefined;
    const replyText =
      `Olá! Sou o Mika de ${firstName(fullName)}. Estou quase pronto para conversar com você de verdade — meu cérebro está sendo configurado pela DOMCO. Em breve vou responder de forma inteligente! Por enquanto, este é apenas um teste de conexão. ✨`;

    let send = await telegramApi(token, "sendMessage", {
      chat_id: chatId,
      text: replyText,
    });

    if (!send.ok && send.status === 401) {
      await admin
        .from("agent_instances")
        .update({ telegram_token_invalid: true, updated_at: new Date().toISOString() })
        .eq("id", agent.id);
      return telegramAck();
    }

    if (!send.ok && send.status === 429) {
      const retryAfter = send.parameters?.retry_after ?? 1;
      await new Promise((r) => setTimeout(r, Math.min(retryAfter, 5) * 1000));
      send = await telegramApi(token, "sendMessage", {
        chat_id: chatId,
        text: replyText,
      });
    }

    if (send.ok) {
      await admin.from("telegram_messages_log").insert({
        agent_instance_id: agent.id,
        user_id: agent.user_id,
        telegram_chat_id: chatId,
        direction: "outgoing",
        message_text: replyText,
        message_type: "text",
        is_first_message: false,
        raw_payload: send.result ?? null,
      });
    } else {
      console.error("sendMessage failed", send);
    }

    return telegramAck();
  } catch (err) {
    console.error("telegram-webhook fatal", err);
    return telegramAck();
  }
});
