'use client';

/**
 * React Query hooks for the Website Analytics page. Mirrors the structure
 * of `src/components/dashboard/use-analytics.ts` but talks to the Umami
 * proxy at /api/v1/website-analytics.
 *
 * All hooks are gated on `currentPortId` so they don't fire before the
 * port is resolved (which would cause a 401 to land in the React Query
 * cache and persist as `isError: true` until staleTime expires).
 */

import { useQuery } from '@tanstack/react-query';

import { apiFetch } from '@/lib/api/client';
import { useUIStore } from '@/stores/ui-store';
import { isCustomRange, type DateRange } from '@/lib/analytics/range';
import type {
  UmamiActiveVisitors,
  UmamiMetricRow,
  UmamiPageviewsSeries,
  UmamiRealtime,
  UmamiSession,
  UmamiSessionActivity,
  UmamiSessionsPage,
  UmamiStats,
  UmamiWebsiteInfo,
} from '@/lib/services/umami.service';

interface MetricResponse<T> {
  metric: string;
  range: DateRange;
  data: T | null;
  /** True when Umami isn't configured for the port. Surfaced as a 200
   *  response (not 4xx) so React Query doesn't infinitely retry - that
   *  retry loop previously saturated the postgres pool and hung the dev
   *  server. UI consumers should check this flag and render the
   *  "set up Umami" empty state. */
  notConfigured?: boolean;
}

function rangeToQuery(range: DateRange): string {
  if (isCustomRange(range)) {
    return `range=custom&from=${range.from}&to=${range.to}`;
  }
  return `range=${range}`;
}

function useUmamiQuery<T>(
  metric: string,
  range: DateRange,
  extraParams = '',
  /** Override the cache key segment that defaults to `range`. Use for
   *  metrics whose response is range-independent (e.g. active visitors)
   *  so the cache isn't fragmented across each date the user has picked. */
  cacheKeySegment?: unknown,
  /** Optional auto-refresh interval. Used for the live active-visitors
   *  badge so the count ticks without a page reload. */
  refetchInterval?: number,
  /** Additional enabled gate (e.g. for session-activity which needs a
   *  selected sessionId before firing). ANDed with the port-id check. */
  enabledGate = true,
) {
  const portId = useUIStore((s) => s.currentPortId);
  return useQuery<MetricResponse<T>>({
    queryKey: ['website-analytics', metric, cacheKeySegment ?? range, portId],
    queryFn: () =>
      apiFetch<MetricResponse<T>>(
        `/api/v1/website-analytics?metric=${metric}&${rangeToQuery(range)}${extraParams}`,
      ),
    staleTime: 30_000, // umami data refreshes constantly; short stale time
    retry: 1,
    enabled: !!portId && enabledGate,
    ...(refetchInterval ? { refetchInterval } : {}),
  });
}

export const useUmamiStats = (range: DateRange) => useUmamiQuery<UmamiStats>('stats', range);
export const useUmamiPageviews = (range: DateRange) =>
  useUmamiQuery<UmamiPageviewsSeries>('pageviews', range);

// Active visitors are server-side range-independent (Umami's /active endpoint
// returns the last-5-minute count regardless of what range we pass). Use a
// fixed cache-key segment so the dashboard tile (range='today') and the
// website-analytics shell (any selected range) share one cache entry instead
// of fragmenting it across every range the user picks.
export const useUmamiActive = (range: DateRange) =>
  useUmamiQuery<UmamiActiveVisitors>('active', range, '', 'fixed', 30_000);

export const useUmamiTopPages = (range: DateRange, limit = 10) =>
  useUmamiQuery<UmamiMetricRow[]>('top-path', range, `&limit=${limit}`);
export const useUmamiTopReferrers = (range: DateRange, limit = 10) =>
  useUmamiQuery<UmamiMetricRow[]>('top-referrer', range, `&limit=${limit}`);
export const useUmamiTopCountries = (range: DateRange, limit = 10) =>
  useUmamiQuery<UmamiMetricRow[]>('top-country', range, `&limit=${limit}`);

// World map needs ALL countries with traffic, not just the top 10 the list
// uses. Umami caps `limit` server-side around 500; 250 covers every ISO
// country we'll ever see in one request.
export const useUmamiAllCountries = (range: DateRange) =>
  useUmamiQuery<UmamiMetricRow[]>('top-country', range, `&limit=250`, `all-${range}`);
export const useUmamiTopBrowsers = (range: DateRange, limit = 10) =>
  useUmamiQuery<UmamiMetricRow[]>('top-browser', range, `&limit=${limit}`);
export const useUmamiTopOS = (range: DateRange, limit = 10) =>
  useUmamiQuery<UmamiMetricRow[]>('top-os', range, `&limit=${limit}`);
export const useUmamiTopDevices = (range: DateRange, limit = 10) =>
  useUmamiQuery<UmamiMetricRow[]>('top-device', range, `&limit=${limit}`);

// Website metadata (name + domain). Range-independent; long stale time
// since the domain rarely changes.
export const useUmamiWebsiteInfo = (range: DateRange) =>
  useUmamiQuery<UmamiWebsiteInfo>('website', range, '', 'website-info');

// Phase 2 - sessions surface. Paginated list of recent sessions plus
// per-session detail + activity stream + weekly engagement heatmap.
export const useUmamiSessions = (
  range: DateRange,
  opts: { page?: number; pageSize?: number; query?: string } = {},
) => {
  const params = new URLSearchParams();
  if (opts.page) params.set('page', String(opts.page));
  if (opts.pageSize) params.set('pageSize', String(opts.pageSize));
  if (opts.query) params.set('query', opts.query);
  const suffix = params.toString() ? `&${params.toString()}` : '';
  const cacheKey = `${range}-${opts.page ?? 1}-${opts.pageSize ?? 25}-${opts.query ?? ''}`;
  return useUmamiQuery<UmamiSessionsPage>('sessions', range, suffix, cacheKey);
};

export const useUmamiSession = (range: DateRange, sessionId: string | null) => {
  const suffix = sessionId ? `&sessionId=${sessionId}` : '';
  return useUmamiQuery<UmamiSession>(
    'session',
    range,
    suffix,
    `session-${sessionId ?? 'none'}`,
    undefined,
    !!sessionId,
  );
};

export const useUmamiSessionActivity = (range: DateRange, sessionId: string | null) => {
  const suffix = sessionId ? `&sessionId=${sessionId}` : '';
  return useUmamiQuery<UmamiSessionActivity[]>(
    'session-activity',
    range,
    suffix,
    `session-activity-${sessionId ?? 'none'}`,
    undefined,
    !!sessionId,
  );
};

export const useUmamiSessionsWeekly = (range: DateRange) =>
  useUmamiQuery<number[][]>('sessions-weekly', range);

// Realtime panel - Umami's /api/realtime endpoint returns last-30-min
// activity. Two cadences: 5 s when the panel is expanded (so it feels
// live) and 60 s when collapsed (so we still know whether to show the
// "Live activity" bar at all - the bar is hidden entirely when there
// are zero visitors and zero events in the last 30 minutes).
export const useUmamiRealtime = (expanded: boolean) =>
  useUmamiQuery<UmamiRealtime>(
    'realtime',
    'today',
    '',
    'realtime-fixed',
    expanded ? 5_000 : 60_000,
  );
