import { useCallback, useEffect, useMemo, useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import type { PortalType } from "@/lib/portalVisibilityConfig";

type VisibilityRule = {
  portal: PortalType;
  function_key: string;
  enabled: boolean;
  owner_user_id: string | null;
  association_id: string | null;
};

export function usePortalVisibility(portal: PortalType, associationId?: string | null) {
  const { user, isAdmin, isStaff } = useAuth();
  const [rules, setRules] = useState<VisibilityRule[]>([]);
  const [loading, setLoading] = useState(true);

  const loadRules = useCallback(async () => {
    setLoading(true);
    const { data } = await supabase
      .from("portal_function_visibility")
      .select("portal,function_key,enabled,owner_user_id,association_id")
      .eq("portal", portal);
    setRules((data as VisibilityRule[]) || []);
    setLoading(false);
  }, [portal]);

  useEffect(() => {
    void loadRules();
  }, [loadRules]);

  const visibleKeys = useMemo(() => {
    const hidden = new Set<string>();
    const shown = new Set<string>();

    rules.filter((rule) => !rule.owner_user_id && !rule.association_id).forEach((rule) => {
      (rule.enabled ? shown : hidden).add(rule.function_key);
    });

    if (user?.id) {
      rules.filter((rule) => rule.owner_user_id === user.id && !rule.association_id).forEach((rule) => {
        if (rule.enabled) {
          hidden.delete(rule.function_key);
          shown.add(rule.function_key);
        } else {
          shown.delete(rule.function_key);
          hidden.add(rule.function_key);
        }
      });
    }

    if (associationId) {
      rules.filter((rule) => !rule.owner_user_id && rule.association_id === associationId).forEach((rule) => {
        if (rule.enabled) {
          hidden.delete(rule.function_key);
          shown.add(rule.function_key);
        } else {
          shown.delete(rule.function_key);
          hidden.add(rule.function_key);
        }
      });
    }

    if (user?.id && associationId) {
      rules.filter((rule) => rule.owner_user_id === user.id && rule.association_id === associationId).forEach((rule) => {
        if (rule.enabled) {
          hidden.delete(rule.function_key);
          shown.add(rule.function_key);
        } else {
          shown.delete(rule.function_key);
          hidden.add(rule.function_key);
        }
      });
    }

    return { hidden, shown };
  }, [associationId, rules, user?.id]);

  const canSee = useCallback((key: string) => {
    if (isAdmin || isStaff) return true;
    return !visibleKeys.hidden.has(key);
  }, [isAdmin, isStaff, visibleKeys.hidden]);

  return { loading, rules, reload: loadRules, canSee };
}
