import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2";

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",
};

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 authHeader = req.headers.get("Authorization") || "";

    const admin = createClient(supabaseUrl, serviceKey);
    // user-scoped client for verifying the caller
    const userClient = createClient(supabaseUrl, Deno.env.get("SUPABASE_ANON_KEY")!, {
      global: { headers: { Authorization: authHeader } },
    });

    const { data: userData } = await userClient.auth.getUser();
    const user = userData?.user;
    if (!user) {
      return new Response(JSON.stringify({ error: "Unauthorized" }), {
        status: 401, headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const body = await req.json();
    const { board_vote_id, base_url, sender_id } = body || {};
    if (!board_vote_id || !base_url) {
      return new Response(JSON.stringify({ error: "board_vote_id and base_url are required" }), {
        status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Verify caller is staff
    const { data: roles } = await admin
      .from("user_roles").select("role").eq("user_id", user.id);
    const isStaff = (roles || []).some((r: any) => r.role === "admin" || r.role === "manager");
    if (!isStaff) {
      return new Response(JSON.stringify({ error: "Forbidden — staff only" }), {
        status: 403, headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Fetch vote
    const { data: vote, error: vErr } = await admin
      .from("board_votes")
      .select("id, title, description, vote_options, status, association_id, associations(name)")
      .eq("id", board_vote_id)
      .single();
    if (vErr || !vote) {
      return new Response(JSON.stringify({ error: "Board vote not found" }), {
        status: 404, headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }
    if (vote.status !== "open") {
      return new Response(JSON.stringify({ error: "Vote is not open" }), {
        status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // (Sender resolution removed — emails now go through Lovable Cloud transactional email.)

    // Fetch board members for this association
    const { data: members } = await admin
      .from("board_members")
      .select("id, member_name, member_email")
      .eq("association_id", vote.association_id);

    const eligible = (members || []).filter((m: any) => m.member_email && /\S+@\S+\.\S+/.test(m.member_email));
    if (eligible.length === 0) {
      return new Response(JSON.stringify({ error: "No board members with email addresses" }), {
        status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const sent: string[] = [];
    const failed: { email: string; reason: string }[] = [];
    const assocName = (vote as any).associations?.name || "Your Association";

    for (const member of eligible) {
      // Upsert token per (vote, member)
      let token: string | null = null;
      const { data: existing } = await admin
        .from("board_vote_email_tokens")
        .select("token")
        .eq("board_vote_id", board_vote_id)
        .eq("board_member_id", member.id)
        .maybeSingle();

      if (existing?.token) {
        token = existing.token;
        await admin.from("board_vote_email_tokens").update({
          email: member.member_email,
          member_name: member.member_name,
          sent_at: new Date().toISOString(),
        }).eq("board_vote_id", board_vote_id).eq("board_member_id", member.id);
      } else {
        const { data: inserted, error: insErr } = await admin
          .from("board_vote_email_tokens")
          .insert({
            board_vote_id,
            board_member_id: member.id,
            email: member.member_email,
            member_name: member.member_name,
            sent_at: new Date().toISOString(),
          })
          .select("token")
          .single();
        if (insErr || !inserted) {
          failed.push({ email: member.member_email, reason: insErr?.message || "Could not create token" });
          continue;
        }
        token = inserted.token;
      }

      const link = `${base_url.replace(/\/$/, "")}/board-vote/${board_vote_id}?token=${token}`;
      const { error: sendErr } = await admin.functions.invoke("send-transactional-email", {
        body: {
          templateName: "board-vote-invite",
          recipientEmail: member.member_email,
          idempotencyKey: `board-vote-${board_vote_id}-${member.id}`,
          templateData: {
            memberName: member.member_name || "Board Member",
            voteTitle: vote.title,
            voteDescription: vote.description || "",
            associationName: assocName,
            link,
          },
        },
      });

      if (sendErr) {
        failed.push({ email: member.member_email, reason: sendErr.message || "Send failed" });
      } else {
        sent.push(member.member_email);
      }
    }

    return new Response(JSON.stringify({ sent: sent.length, failed: failed.length, details: { sent, failed } }), {
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  } catch (err: any) {
    console.error("send-board-vote-invites error:", err);
    return new Response(JSON.stringify({ error: err.message || String(err) }), {
      status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  }
});

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