import { createClient } from "https://esm.sh/@supabase/supabase-js@2.99.1";

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

// Compute next run date from a base date and frequency, ensuring result > today.
function computeNextRunDate(baseISO: string, frequency: string, today: Date): string {
  const d = new Date(baseISO + "T12:00:00");
  const addByFreq = (date: Date) => {
    switch (frequency) {
      case "monthly": date.setMonth(date.getMonth() + 1); break;
      case "quarterly": date.setMonth(date.getMonth() + 3); break;
      case "semi-annual": date.setMonth(date.getMonth() + 6); break;
      case "annual": date.setFullYear(date.getFullYear() + 1); break;
      default: date.setMonth(date.getMonth() + 1);
    }
  };
  // Advance until strictly after today
  while (d <= today) addByFreq(d);
  return d.toISOString().split("T")[0];
}

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

  try {
    const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
    const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
    const supabase = createClient(supabaseUrl, serviceKey);

    const today = new Date();
    const todayISO = today.toISOString().split("T")[0];

    // Find all rules due to run
    const { data: dueRules, error: rulesErr } = await supabase
      .from("association_fee_rules")
      .select("*")
      .eq("auto_post_enabled", true)
      .lte("next_run_date", todayISO);

    if (rulesErr) throw rulesErr;
    if (!dueRules || dueRules.length === 0) {
      return new Response(JSON.stringify({ processed: 0, posted: 0 }), {
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    let totalPosted = 0;
    const results: any[] = [];

    for (const rule of dueRules) {
      const associationId = rule.association_id;

      // Load units + active owners for this association
      const [{ data: units }, { data: owners }] = await Promise.all([
        supabase
          .from("units")
          .select("id, monthly_assessment, assessment_amount_one, assessment_account_id")
          .eq("association_id", associationId),
        supabase
          .from("owners")
          .select("id, unit_id")
          .eq("association_id", associationId)
          .eq("status", "active"),
      ]);

      const ownerByUnit = new Map<string, string>();
      (owners || []).forEach((o: any) => { if (o.unit_id) ownerByUnit.set(o.unit_id, o.id); });

      const entries = (units || []).flatMap((u: any) => {
        const ownerId = ownerByUnit.get(u.id);
        if (!ownerId) return [];
        const amount = u.assessment_amount_one ?? u.monthly_assessment ?? rule.default_assessment_amount ?? 0;
        if (!amount || amount <= 0) return [];
        return [{
          association_id: associationId,
          owner_id: ownerId,
          unit_id: u.id,
          date: todayISO,
          credit: 0,
          debit: amount,
          transaction_type: "assessment",
          description: "Assessment (auto-posted)",
        }];
      });

      let posted = 0;
      if (entries.length) {
        const { error: insErr } = await supabase.from("owner_ledger_entries").insert(entries);
        if (insErr) {
          console.error(`Failed posting for association ${associationId}:`, insErr);
          results.push({ associationId, error: insErr.message });
          continue;
        }
        posted = entries.length;
        totalPosted += posted;
      }

      // Advance the cycle
      const newNext = computeNextRunDate(rule.next_run_date || todayISO, rule.assessment_frequency || "monthly", today);
      await supabase
        .from("association_fee_rules")
        .update({ last_run_date: todayISO, next_run_date: newNext })
        .eq("id", rule.id);

      results.push({ associationId, posted, next_run_date: newNext });
    }

    return new Response(JSON.stringify({ processed: dueRules.length, posted: totalPosted, results }), {
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  } catch (err) {
    console.error("post-recurring-assessments error:", err);
    return new Response(JSON.stringify({ error: (err as Error).message }), {
      status: 500,
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  }
});
