import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from "react";
import { supabase } from "@/integrations/supabase/client";

interface TickerCounts {
  tasks: number;
  arc_applications: number;
  homeowner_requests: number;
  bill_approvals: number;
  board_votes: number;
  reminders: number;
  projects: number;
}

const defaultCounts: TickerCounts = {
  tasks: 0,
  arc_applications: 0,
  homeowner_requests: 0,
  bill_approvals: 0,
  board_votes: 0,
  reminders: 0,
  projects: 0,
};

const TickerContext = createContext<TickerCounts>(defaultCounts);

export function useTickerCounts() {
  return useContext(TickerContext);
}

export function TickerProvider({ children }: { children: ReactNode }) {
  const [counts, setCounts] = useState<TickerCounts>(defaultCounts);

  const fetchCounts = useCallback(async () => {
    const [tasks, arc, homeowner, pendingBills, allApprovals, votes, reminders, projects] = await Promise.all([
      supabase.from("tasks").select("id", { count: "exact", head: true }).neq("status", "completed"),
      supabase.from("arc_applications").select("id", { count: "exact", head: true }).in("status", ["submitted", "under_review"]),
      supabase.from("homeowner_requests").select("id", { count: "exact", head: true }).in("status", ["open", "in_progress"]),
      supabase.from("bills").select("id").eq("status", "pending"),
      supabase.from("bill_approvals").select("bill_id, status").not("bill_id", "is", null),
      supabase.from("board_votes").select("id", { count: "exact", head: true }).eq("status", "open"),
      supabase.from("reminders").select("id", { count: "exact", head: true }).eq("status", "pending"),
      supabase.from("projects").select("id", { count: "exact", head: true }).in("status", ["active", "in_progress"]),
    ]);

    // A pending bill is only "actionable" if it has zero approvals or at
    // least one still-pending approval. Bills where every approval is
    // already resolved (approved/denied) but the bill row is stuck on
    // 'pending' should NOT contribute to the badge.
    const approvalsByBill = new Map<string, string[]>();
    (allApprovals.data || []).forEach((a: any) => {
      const arr = approvalsByBill.get(a.bill_id) || [];
      arr.push(a.status);
      approvalsByBill.set(a.bill_id, arr);
    });
    let actionable = 0;
    (pendingBills.data || []).forEach((b: any) => {
      const s = approvalsByBill.get(b.id);
      if (!s || s.length === 0 || s.some((v) => v === "pending")) actionable += 1;
    });

    setCounts({
      tasks: tasks.count ?? 0,
      arc_applications: arc.count ?? 0,
      homeowner_requests: homeowner.count ?? 0,
      bill_approvals: actionable,
      board_votes: votes.count ?? 0,
      reminders: reminders.count ?? 0,
      projects: projects.count ?? 0,
    });
  }, []);

  useEffect(() => {
    fetchCounts();
  }, [fetchCounts]);

  // Real-time subscriptions
  useEffect(() => {
    const tables = [
      "tasks",
      "arc_applications",
      "homeowner_requests",
      "bills",
      "board_votes",
      "reminders",
      "projects",
    ];

    const channel = supabase
      .channel("ticker-counts")
      .on("postgres_changes", { event: "*", schema: "public", table: "tasks" }, () => fetchCounts())
      .on("postgres_changes", { event: "*", schema: "public", table: "arc_applications" }, () => fetchCounts())
      .on("postgres_changes", { event: "*", schema: "public", table: "homeowner_requests" }, () => fetchCounts())
      .on("postgres_changes", { event: "*", schema: "public", table: "bills" }, () => fetchCounts())
      .on("postgres_changes", { event: "*", schema: "public", table: "board_votes" }, () => fetchCounts())
      .on("postgres_changes", { event: "*", schema: "public", table: "reminders" }, () => fetchCounts())
      .on("postgres_changes", { event: "*", schema: "public", table: "projects" }, () => fetchCounts())
      .subscribe();

    return () => {
      supabase.removeChannel(channel);
    };
  }, [fetchCounts]);

  return (
    <TickerContext.Provider value={counts}>
      {children}
    </TickerContext.Provider>
  );
}
