"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { apiClient } from "@/lib/api";
import { paymentMethodListSchema, type PaymentMethodList } from "@customer-portal/domain/payments";
import { useAuthSession } from "@/features/auth/services/auth.store";

type Tone = "info" | "success" | "warning" | "error";

interface UsePaymentRefreshOptions {
  // Refetch function from usePaymentMethods
  refetch: () => Promise<{ data: PaymentMethodList | undefined }>;
  // When true, attaches focus/visibility listeners to refresh automatically
  attachFocusListeners?: boolean;
  // Optional custom detector for whether payment methods exist
  hasMethods?: (data?: PaymentMethodList) => boolean;
}

export function usePaymentRefresh({
  refetch,
  attachFocusListeners = false,
  hasMethods,
}: UsePaymentRefreshOptions) {
  const { isAuthenticated } = useAuthSession();
  const hideToastTimeout = useRef<number | null>(null);
  const [toast, setToast] = useState<{ visible: boolean; text: string; tone: Tone }>({
    visible: false,
    text: "",
    tone: "info",
  });

  const clearHideToastTimeout = () => {
    if (hideToastTimeout.current) {
      clearTimeout(hideToastTimeout.current);
      hideToastTimeout.current = null;
    }
  };

  const triggerRefresh = useCallback(async () => {
    // Don't trigger refresh if not authenticated
    if (!isAuthenticated) {
      return;
    }

    setToast({ visible: true, text: "Refreshing payment methods...", tone: "info" });
    try {
      try {
        await apiClient.POST("/api/invoices/payment-methods/refresh");
      } catch {
        // Soft-fail cache refresh, still attempt refetch
        // Payment methods cache refresh failed - silently continue
      }
      const result = await refetch();
      const parsed = paymentMethodListSchema.safeParse(result.data ?? null);
      const list = parsed.success ? parsed.data : { paymentMethods: [], totalCount: 0 };
      const has =
        typeof hasMethods === "function"
          ? hasMethods(parsed.success ? parsed.data : undefined)
          : list.totalCount > 0 || list.paymentMethods.length > 0;
      setToast({
        visible: true,
        text: has ? "Payment methods updated" : "No payment method found yet",
        tone: has ? "success" : "warning",
      });
    } catch {
      setToast({ visible: true, text: "Could not refresh payment methods", tone: "warning" });
    } finally {
      clearHideToastTimeout();
      hideToastTimeout.current = window.setTimeout(() => {
        setToast(t => ({ ...t, visible: false }));
        hideToastTimeout.current = null;
      }, 2200);
    }
  }, [isAuthenticated, refetch, hasMethods]);

  useEffect(() => {
    return () => {
      clearHideToastTimeout();
    };
  }, []);

  useEffect(() => {
    if (!attachFocusListeners) return;

    const onFocus = () => {
      void triggerRefresh();
    };
    const onVis = () => {
      if (document.visibilityState === "visible") void triggerRefresh();
    };
    window.addEventListener("focus", onFocus);
    document.addEventListener("visibilitychange", onVis);
    return () => {
      window.removeEventListener("focus", onFocus);
      document.removeEventListener("visibilitychange", onVis);
    };
  }, [attachFocusListeners, triggerRefresh]);

  return { toast, triggerRefresh, setToast } as const;
}
