"use client";

import { toastApiError } from "@/lib/toast-api-error";
import * as React from "react";
import { Filter, Loader2, X } from "lucide-react";
import { toast } from "sonner";

import {
  listImpersonationOptions,
  updateImpersonationSelection,
} from "@/app/customer/_lib/admin/impersonation-api";
import {
  dispatchImpersonationScopeChanged,
  dispatchOpenPortfolioScope,
  IMPERSONATION_SCOPE_CHANGED_EVENT,
} from "@/app/customer/_lib/admin/impersonation-scope";
import { Button } from "@/components/ui/button";

type PortfolioScopeBannerProps = {
  tenant: string;
  canUsePortfolioScope?: boolean;
};

/**
 * Persistent indication when Corporate Portfolio Scope (Users/Customers) is active.
 * Distinct from login impersonation ({@see ImpersonationBanner}).
 */
export function PortfolioScopeBanner({
  tenant: _tenant,
  canUsePortfolioScope = false,
}: PortfolioScopeBannerProps) {
  const [userCount, setUserCount] = React.useState(0);
  const [customerCount, setCustomerCount] = React.useState(0);
  const [visibleCapability, setVisibleCapability] = React.useState(canUsePortfolioScope);
  const [clearing, setClearing] = React.useState(false);

  const applyCounts = React.useCallback((users: number[], customers: number[]) => {
    setUserCount(users.length);
    setCustomerCount(customers.length);
  }, []);

  React.useEffect(() => {
    if (canUsePortfolioScope) {
      setVisibleCapability(true);
    }
  }, [canUsePortfolioScope]);

  React.useEffect(() => {
    let cancelled = false;
    let retryTimeoutId: number | undefined;

    async function load(attempt = 0) {
      try {
        // limit=1 is fine for capability + effective_* counts: options GET must not
        // mutate Scope cookies (those are owned by selection POST only).
        const data = await listImpersonationOptions({ limit: 1 });
        if (cancelled) return;
        setVisibleCapability(
          Boolean(data.capabilities.can_impersonate_multiple) || canUsePortfolioScope,
        );
        applyCounts(data.effective_user_ids ?? [], data.effective_customer_ids ?? []);
      } catch {
        if (cancelled) return;
        if (attempt < 1) {
          retryTimeoutId = window.setTimeout(() => {
            if (!cancelled) void load(attempt + 1);
          }, 1500);
          return;
        }
        // Keep session capability; only clear counts — do not hide Scope permanently.
        setVisibleCapability(canUsePortfolioScope);
        if (!canUsePortfolioScope) applyCounts([], []);
      }
    }

    void load();
    return () => {
      cancelled = true;
      if (retryTimeoutId !== undefined) window.clearTimeout(retryTimeoutId);
    };
  }, [applyCounts, canUsePortfolioScope]);

  React.useEffect(() => {
    const onScopeChanged = (event: Event) => {
      const detail = (event as CustomEvent<{
        impersonatedUserIds?: number[];
        impersonatedCustomerIds?: number[];
      }>).detail;
      applyCounts(detail?.impersonatedUserIds ?? [], detail?.impersonatedCustomerIds ?? []);
    };

    window.addEventListener(IMPERSONATION_SCOPE_CHANGED_EVENT, onScopeChanged);
    return () => window.removeEventListener(IMPERSONATION_SCOPE_CHANGED_EVENT, onScopeChanged);
  }, [applyCounts]);

  const active = visibleCapability && (userCount > 0 || customerCount > 0);
  if (!active) return null;

  const parts: string[] = [];
  if (userCount > 0) {
    parts.push(`${userCount} user${userCount === 1 ? "" : "s"}`);
  }
  if (customerCount > 0) {
    parts.push(`${customerCount} customer${customerCount === 1 ? "" : "s"}`);
  }

  const handleClear = async () => {
    setClearing(true);
    try {
      await updateImpersonationSelection({ userIds: [], customerIds: [] });
      applyCounts([], []);
      dispatchImpersonationScopeChanged({
        userIds: [],
        customerIds: [],
        clearPageSearchParams: true,
      });
      toast.success("Portfolio scope cleared");
    } catch (error) {
      toastApiError(error, "Could not clear scope.");
    } finally {
      setClearing(false);
    }
  };

  return (
    <div className="border-b border-border bg-muted/50 px-4 py-2 text-sm text-foreground">
      <div className="mx-auto flex max-w-7xl items-center justify-between gap-3">
        <div className="flex min-w-0 items-center gap-2">
          <Filter className="size-3.5 shrink-0 text-muted-foreground" />
          <span className="truncate">
            <span className="font-medium">Portfolio Scope active</span>
            {parts.length > 0 ? (
              <span className="text-muted-foreground">
                {" "}
                · {parts.join(" · ")}
              </span>
            ) : null}
          </span>
        </div>
        <div className="flex shrink-0 items-center gap-2">
          <Button
            size="sm"
            variant="outline"
            className="h-7"
            onClick={() => dispatchOpenPortfolioScope()}
          >
            Change
          </Button>
          <Button
            size="sm"
            variant="outline"
            className="h-7 gap-1"
            disabled={clearing}
            onClick={() => void handleClear()}
          >
            {clearing ? <Loader2 className="size-3.5 animate-spin" /> : <X className="size-3.5" />}
            Clear
          </Button>
        </div>
      </div>
    </div>
  );
}
