'use client';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { Button } from '@/components/ui/primitives/Button';
/**
 * FraudDashboard — top-level island for the /admin/affiliates/fraud page.
 *
 * Fetches: stats, event queue, analytics (events-over-time + fp-rate).
 * Delegates evidence fetching to FraudEvidenceDrawer (self-fetches).
 * Delegates filter bar rendering to FraudEventQueue (renders it when filters/onFiltersChange are passed).
 * Delegates FraudActionBar rendering to FraudEvidenceDrawer (renders it when actionProps given).
 */
import { HydratedIsland } from '@/components/HydratedIsland';
import { useMemo, useState } from 'react';
import { useUrlFilterState } from '@/lib/url/useUrlFilterState';
import { makeFraudDashboardCodec } from '@/lib/url/codecs/fraudDashboardCodec';
import { HISTORY } from '@/lib/url/historyPolicy';
import { useQuery } from '@tanstack/react-query';
import { useT } from '@/lib/i18n/react';
import { fetchWithRefresh } from '@/lib/api/refresh-on-401';
import { FraudStatusStrip, type FraudStats } from './FraudStatusStrip';
import {
  FraudEventQueue,
  type FraudEventRow,
  FRAUD_QUEUE_FILTERS_DEFAULT,
} from './FraudEventQueue';
import { FraudEvidenceDrawer } from './FraudEvidenceDrawer';
import { FraudConfigCards } from './FraudConfigCards';
import {
  FraudEventsOverTime,
  FalsePositiveRateWidget,
  TopFiringAdaptersWidget,
  MoneyProtectedWidget,
  type EventsOverTimeRow,
  type FpRateRow,
  type TopAdapterRow,
} from './FraudAnalyticsWidgets';

// ─── Component ────────────────────────────────────────────────────────────────

function FraudDashboardInner() {
  const t = useT('admin_affiliates');
  const tCommon = useT('common');
  const codec = useMemo(() => makeFraudDashboardCodec('/admin/affiliates/fraud'), []);
  const { state: filters, setUrlState } = useUrlFilterState({
    initial: { ...FRAUD_QUEUE_FILTERS_DEFAULT },
    codec,
  });
  const [expandedId, setExpandedId] = useState<string | null>(null);

  // ── Stats ──────────────────────────────────────────────────────────────────
  const statsQ = useQuery<FraudStats>({
    queryKey: ['fraud-stats'],
    queryFn: async () => {
      const res = await fetchWithRefresh('/api/admin/affiliates/fraud/stats');
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as { stats: FraudStats };
      return json.stats;
    },
    staleTime: 30_000,
  });

  // ── Event queue ────────────────────────────────────────────────────────────
  const params = new URLSearchParams();
  if (filters.decision_point !== 'all') params.set('decision_point', filters.decision_point);
  if (filters.action !== 'all') params.set('action', filters.action);
  if (filters.adapter !== 'all') params.set('adapter', filters.adapter);
  if (filters.status) params.set('status', filters.status);

  const eventsQ = useQuery<FraudEventRow[]>({
    queryKey: ['fraud-events', filters],
    queryFn: async () => {
      const res = await fetchWithRefresh(`/api/admin/affiliates/fraud/events?${params.toString()}`);
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as { events: FraudEventRow[] };
      return json.events;
    },
    staleTime: 30_000,
  });

  // ── Analytics: events over time ───────────────────────────────────────────
  const analyticsEventsQ = useQuery<EventsOverTimeRow[]>({
    queryKey: ['fraud-analytics-events-over-time'],
    queryFn: async () => {
      const res = await fetchWithRefresh(
        '/api/admin/affiliates/fraud/analytics?widget=events_over_time',
      );
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as { data: EventsOverTimeRow[] };
      return json.data;
    },
    staleTime: 60_000,
  });

  // ── Analytics: false-positive rate ────────────────────────────────────────
  const analyticsFpQ = useQuery<FpRateRow[]>({
    queryKey: ['fraud-analytics-fp-rate'],
    queryFn: async () => {
      const res = await fetchWithRefresh(
        '/api/admin/affiliates/fraud/analytics?widget=false_positive_rate',
      );
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as { data: FpRateRow[] };
      return json.data;
    },
    staleTime: 60_000,
  });

  // ── Analytics: top-firing adapters ───────────────────────────────────────
  const analyticsTopAdaptersQ = useQuery<TopAdapterRow[]>({
    queryKey: ['fraud-analytics-top-adapters'],
    queryFn: async () => {
      const res = await fetchWithRefresh(
        '/api/admin/affiliates/fraud/analytics?widget=top_firing_adapters',
      );
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as { data: TopAdapterRow[] };
      return json.data;
    },
    staleTime: 60_000,
  });

  // ── Analytics: money protected ────────────────────────────────────────────
  const analyticsMoneyProtectedQ = useQuery<{
    quarantined_agorot: number;
    recovered_90d_agorot: number;
  }>({
    queryKey: ['fraud-analytics-money-protected'],
    queryFn: async () => {
      const res = await fetchWithRefresh(
        '/api/admin/affiliates/fraud/analytics?widget=money_protected',
      );
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as {
        data: { quarantined_agorot: number; recovered_90d_agorot: number };
      };
      return json.data;
    },
    staleTime: 60_000,
  });

  // ── Resolve expanded event for drawer actionProps ─────────────────────────
  const events = eventsQ.data ?? [];
  const expandedEvent = expandedId ? (events.find((e) => e.id === expandedId) ?? null) : null;

  // ─────────────────────────────────────────────────────────────────────────

  if (eventsQ.isError) {
    return (
      <ErrorState
        title={tCommon('error_loading')}
        action={
          <Button variant="secondary" size="sm" onClick={() => eventsQ.refetch()}>
            {tCommon('retry')}
          </Button>
        }
      />
    );
  }
  return (
    <div className="space-y-6">
      {/* [A] Status strip */}
      {statsQ.data && <FraudStatusStrip stats={statsQ.data} />}

      {/* [B] Event queue + evidence drawer */}
      <section aria-label={t('fraud_section_queue')}>
        <FraudEventQueue
          events={events}
          expandedId={expandedId}
          onExpand={setExpandedId}
          filters={filters}
          onFiltersChange={(next) => setUrlState(next, HISTORY.tweak)}
        />

        {expandedId && expandedEvent && (
          <FraudEvidenceDrawer
            eventId={expandedId}
            onClose={() => setExpandedId(null)}
            actionProps={{
              decisionPoint: expandedEvent.decision_point,
              fraudAction: expandedEvent.action,
              amountAgorot: expandedEvent.amount_agorot,
            }}
          />
        )}
      </section>

      {/* [C] Analytics widgets */}
      <section
        aria-label={t('fraud_section_analytics')}
        className="grid grid-cols-1 gap-4 md:grid-cols-2"
      >
        <FraudEventsOverTime rows={analyticsEventsQ.data ?? []} />
        <FalsePositiveRateWidget
          rows={analyticsFpQ.data ?? []}
          overallRate={statsQ.data?.false_positive_rate_pct ?? null}
        />
        <TopFiringAdaptersWidget rows={analyticsTopAdaptersQ.data ?? []} />
        <MoneyProtectedWidget
          quarantinedAgorot={analyticsMoneyProtectedQ.data?.quarantined_agorot ?? 0}
          recovered90dAgorot={analyticsMoneyProtectedQ.data?.recovered_90d_agorot ?? 0}
        />
      </section>

      {/* [D] Fraud adapter config cards */}
      <section aria-label={t('fraud_section_config')}>
        <FraudConfigCards />
      </section>
    </div>
  );
}

export function FraudDashboard() {
  return (
    <HydratedIsland>
      <FraudDashboardInner />
    </HydratedIsland>
  );
}
