import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
import { mydb } from "../../lib/mySupabase.ts";
import { corsHeaders, jsonResponse, errorResponse } from "../../lib/utils.ts";

/**
 * POST /notifications-worker
 * Worker que processa fila de notificações pendentes
 * Deve ser executado via cron job a cada 1-5 minutos
 *
 * Processa:
 * - SMS via Twilio
 * - Email via SendGrid/Resend
 * - WhatsApp via Twilio
 * - Push notifications
 */

const TWILIO_SID = Deno.env.get("TWILIO_SID");
const TWILIO_AUTH_TOKEN = Deno.env.get("TWILIO_AUTH_TOKEN");
const TWILIO_FROM = Deno.env.get("TWILIO_FROM");

async function sendSMS(to: string, message: string) {
  if (!TWILIO_SID || !TWILIO_AUTH_TOKEN || !TWILIO_FROM) {
    console.warn("[SMS] Twilio não configurado");
    return { success: false, error: "Twilio not configured" };
  }

  const url = `https://api.twilio.com/2010-04-01/Accounts/${TWILIO_SID}/Messages.json`;
  const auth = btoa(`${TWILIO_SID}:${TWILIO_AUTH_TOKEN}`);

  try {
    const res = await fetch(url, {
      method: "POST",
      headers: {
        Authorization: `Basic ${auth}`,
        "Content-Type": "application/x-www-form-urlencoded",
      },
      body: new URLSearchParams({
        To: to,
        From: TWILIO_FROM!,
        Body: message,
      }),
    });

    const data = await res.json();

    if (!res.ok) {
      return { success: false, error: data.message || "SMS failed" };
    }

    return { success: true, sid: data.sid };
  } catch (error) {
    console.error("[SMS] Error:", error);
    return { success: false, error: String(error) };
  }
}

async function sendEmail(to: string, subject: string, body: string) {
  // TODO: Implementar SendGrid ou Resend
  console.log("[Email] Would send to:", to, subject);
  return { success: true, message: "Email sending not implemented yet" };
}

async function sendWhatsApp(to: string, message: string) {
  if (!TWILIO_SID || !TWILIO_AUTH_TOKEN) {
    return { success: false, error: "Twilio not configured" };
  }

  const url = `https://api.twilio.com/2010-04-01/Accounts/${TWILIO_SID}/Messages.json`;
  const auth = btoa(`${TWILIO_SID}:${TWILIO_AUTH_TOKEN}`);

  try {
    const res = await fetch(url, {
      method: "POST",
      headers: {
        Authorization: `Basic ${auth}`,
        "Content-Type": "application/x-www-form-urlencoded",
      },
      body: new URLSearchParams({
        To: `whatsapp:${to}`,
        From: `whatsapp:${TWILIO_FROM}`,
        Body: message,
      }),
    });

    const data = await res.json();

    if (!res.ok) {
      return { success: false, error: data.message || "WhatsApp failed" };
    }

    return { success: true, sid: data.sid };
  } catch (error) {
    return { success: false, error: String(error) };
  }
}

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

  try {
    console.log("[Worker] Iniciando processamento de notificações...");

    // 1. Buscar notificações pendentes ou agendadas para agora
    const now = new Date().toISOString();

    const { data: notifications, error: fetchError } = await mydb
      .from("notifications_queue")
      .select("*")
      .eq("status", "pending")
      .or(`scheduled_at.is.null,scheduled_at.lte.${now}`)
      .lt("attempts", 3)
      .order("created_at", { ascending: true })
      .limit(50); // Processa 50 por vez

    if (fetchError) {
      console.error("[Worker] Erro ao buscar notificações:", fetchError);
      return errorResponse(fetchError.message, 500);
    }

    if (!notifications || notifications.length === 0) {
      console.log("[Worker] Nenhuma notificação pendente");
      return jsonResponse({
        success: true,
        processed: 0,
        message: "No pending notifications",
      });
    }

    console.log(`[Worker] Processando ${notifications.length} notificações...`);

    let processed = 0;
    let failed = 0;
    const results = [];

    for (const notification of notifications) {
      const { id, type, payload, attempts } = notification;

      // Marcar como processando
      await mydb
        .from("notifications_queue")
        .update({ status: "processing" })
        .eq("id", id);

      let result;
      let success = false;

      try {
        switch (type) {
          case "sms":
            result = await sendSMS(payload.to, payload.message);
            success = result.success;
            break;

          case "email":
            result = await sendEmail(payload.to, payload.subject, payload.body);
            success = result.success;
            break;

          case "whatsapp":
            result = await sendWhatsApp(payload.to, payload.message);
            success = result.success;
            break;

          case "push":
            // TODO: Implementar push notifications (Firebase, OneSignal, etc)
            result = { success: false, error: "Push not implemented" };
            break;

          default:
            result = { success: false, error: "Unknown notification type" };
        }

        if (success) {
          // Marcar como enviada
          await mydb
            .from("notifications_queue")
            .update({
              status: "sent",
              sent_at: new Date().toISOString(),
              attempts: attempts + 1,
            })
            .eq("id", id);

          processed++;
        } else {
          // Incrementar tentativas e marcar erro
          const newAttempts = attempts + 1;
          const finalStatus = newAttempts >= 3 ? "failed" : "pending";

          await mydb
            .from("notifications_queue")
            .update({
              status: finalStatus,
              attempts: newAttempts,
              last_error: result.error || "Unknown error",
            })
            .eq("id", id);

          failed++;
        }

        results.push({
          id,
          type,
          success,
          error: result.error || null,
        });
      } catch (error) {
        console.error(`[Worker] Erro ao processar notificação ${id}:`, error);

        await mydb
          .from("notifications_queue")
          .update({
            status: "pending",
            attempts: attempts + 1,
            last_error: String(error),
          })
          .eq("id", id);

        failed++;
      }
    }

    console.log(
      `[Worker] Concluído: ${processed} enviadas, ${failed} falharam`
    );

    return jsonResponse({
      success: true,
      processed,
      failed,
      total: notifications.length,
      results,
    });
  } catch (error: unknown) {
    console.error("[Worker] Erro geral:", error);
    const err = error as Error;
    return errorResponse(err.message, 500);
  }
});
