const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Headers":
    "authorization, x-client-info, apikey, content-type, x-supabase-client-platform, x-supabase-client-platform-version, x-supabase-client-runtime, x-supabase-client-runtime-version",
};

function escapeHtml(str: string): string {
  return str
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}

const RATE_LIMIT_MS = 10_000; // 10 seconds between requests per IP+contact
const IP_RATE_LIMIT_MS = 60_000; // 1 minute window for global IP limit
const IP_MAX_REQUESTS = 5; // max 5 requests per minute per IP
const rateLimitMap = new Map<string, number>();
const ipRequestLog = new Map<string, number[]>();

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

  try {
    const { address, contact, fiber_available, max_speed } = await req.json();

    if (!address || !contact) {
      return new Response(
        JSON.stringify({ error: "Missing address or contact" }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Validate inputs
    if (typeof address !== "string" || address.length > 500) {
      return new Response(
        JSON.stringify({ error: "Invalid address" }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }
    if (typeof contact !== "string" || contact.length > 254) {
      return new Response(
        JSON.stringify({ error: "Invalid contact" }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Server-side contact format validation
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    const phoneRegex = /^\+?[1-9]\d{1,14}$/;
    const isEmailContact = contact.includes("@");

    if (isEmailContact && !emailRegex.test(contact)) {
      return new Response(
        JSON.stringify({ error: "Invalid email format" }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }
    if (!isEmailContact && !phoneRegex.test(contact)) {
      return new Response(
        JSON.stringify({ error: "Invalid phone format" }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Server-side rate limiting
    const clientIp = req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || "unknown";
    
    // Global per-IP rate limit: max 5 requests per minute
    const now = Date.now();
    const ipLog = ipRequestLog.get(clientIp) || [];
    const recentIpRequests = ipLog.filter(ts => now - ts < IP_RATE_LIMIT_MS);
    if (recentIpRequests.length >= IP_MAX_REQUESTS) {
      return new Response(
        JSON.stringify({ error: "Too many requests. Please wait before trying again." }),
        { status: 429, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Per IP+contact rate limit: 10s cooldown
    const rateLimitKey = `${clientIp}:${contact}`;
    const lastRequest = rateLimitMap.get(rateLimitKey);
    if (lastRequest && now - lastRequest < RATE_LIMIT_MS) {
      return new Response(
        JSON.stringify({ error: "Too many requests. Please wait before trying again." }),
        { status: 429, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }
    rateLimitMap.set(rateLimitKey, now);
    recentIpRequests.push(now);
    ipRequestLog.set(clientIp, recentIpRequests);
    
    // Clean old entries periodically
    if (rateLimitMap.size > 1000) {
      for (const [key, ts] of rateLimitMap) {
        if (now - ts > RATE_LIMIT_MS) rateLimitMap.delete(key);
      }
    }
    if (ipRequestLog.size > 500) {
      for (const [key, timestamps] of ipRequestLog) {
        const valid = timestamps.filter(ts => now - ts < IP_RATE_LIMIT_MS);
        if (valid.length === 0) ipRequestLog.delete(key);
        else ipRequestLog.set(key, valid);
      }
    }

    const safeAddress = escapeHtml(address);
    const safeContact = escapeHtml(contact);

    const isEmail = contact.includes("@");
    const contactType = isEmail ? "Courriel" : "Mobile";
    const availability = fiber_available ? "✅ Disponible" : "❌ Non disponible";
    const speedText = max_speed && max_speed > 0
      ? max_speed >= 1000 ? `${(max_speed / 1000).toFixed(1)} Gbit/s` : `${max_speed} Mbit/s`
      : "N/A";

    const htmlBody = `
      <h2>Nouvelle demande de disponibilité fibre</h2>
      <table style="border-collapse:collapse;width:100%;max-width:500px;">
        <tr><td style="padding:8px;border:1px solid #ddd;font-weight:bold;">Adresse</td><td style="padding:8px;border:1px solid #ddd;">${safeAddress}</td></tr>
        <tr><td style="padding:8px;border:1px solid #ddd;font-weight:bold;">Disponibilité</td><td style="padding:8px;border:1px solid #ddd;">${availability}</td></tr>
        <tr><td style="padding:8px;border:1px solid #ddd;font-weight:bold;">Vitesse max</td><td style="padding:8px;border:1px solid #ddd;">${speedText}</td></tr>
        <tr><td style="padding:8px;border:1px solid #ddd;font-weight:bold;">${contactType}</td><td style="padding:8px;border:1px solid #ddd;">${safeContact}</td></tr>
      </table>
    `;

    const MAILJET_API_KEY = Deno.env.get("MAILJET_API_KEY")!;
    const MAILJET_SECRET_KEY = Deno.env.get("MAILJET_SECRET_KEY")!;

    const response = await fetch("https://api.mailjet.com/v3.1/send", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: "Basic " + btoa(`${MAILJET_API_KEY}:${MAILJET_SECRET_KEY}`),
      },
      body: JSON.stringify({
        Messages: [
          {
            From: { Email: "louis.targo@gmail.com", Name: "Targo - Vérification" },
            To: [{ Email: "support@targo.ca", Name: "Support Targo" }],
            Subject: `Nouvelle demande – ${fiber_available ? "Fibre disponible" : "Fibre non disponible"} – ${safeContact}`,
            HTMLPart: htmlBody,
          },
        ],
      }),
    });

    const result = await response.text();

    if (!response.ok) {
      console.error("Mailjet error:", result);
      return new Response(
        JSON.stringify({ error: "Email send failed" }),
        { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    return new Response(
      JSON.stringify({ success: true }),
      { headers: { ...corsHeaders, "Content-Type": "application/json" } }
    );
  } catch (err) {
    console.error("send-lead-email error:", err);
    return new Response(
      JSON.stringify({ error: "Internal server error" }),
      { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
    );
  }
});
