import { useEffect, useState, useCallback } from 'react';
import { useShadeContext } from './ShadeProvider.js';

export interface ShadeState {
  identity: {
    fingerprint: string | null;
    registrationId: number | null;
    lastInitialized: number | null;
    lastRotated: number | null;
  };
  sessions: Array<{
    address: string;
    remoteIdentityKeyHash: string;
    messageCountSent: number;
    messageCountReceived: number;
    lastActivity: number;
    dhRatchetSteps: number;
  }>;
  prekeys: {
    oneTimeRemaining: number;
    lastGenerated: number | null;
    lastConsumed: number | null;
    signedPreKeyId: number | null;
    signedPreKeyLastRotated: number | null;
  };
  retiredIdentities: number;
  server: {
    registeredIdentities: string[];
    totalBundleFetches: number;
    totalReplenishes: number;
    totalDeleted: number;
    totalRateLimited: number;
  };
}

export interface UseShadeStateResult {
  state: ShadeState | null;
  loading: boolean;
  error: Error | null;
  refresh: () => Promise<void>;
}

/**
 * Hook that polls the observer's /api/state endpoint at the configured interval.
 */
export function useShadeState(): UseShadeStateResult {
  const ctx = useShadeContext();
  const [state, setState] = useState<ShadeState | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  const fetchState = useCallback(async () => {
    try {
      const res = await fetch(`${ctx.observerUrl}/api/state`, {
        headers: { Authorization: `Bearer ${ctx.token}` },
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const json = (await res.json()) as ShadeState;
      setState(json);
      setError(null);
    } catch (err) {
      setError(err as Error);
    } finally {
      setLoading(false);
    }
  }, [ctx.observerUrl, ctx.token]);

  useEffect(() => {
    fetchState();
    const interval = setInterval(fetchState, ctx.pollIntervalMs);
    return () => clearInterval(interval);
  }, [fetchState, ctx.pollIntervalMs]);

  return { state, loading, error, refresh: fetchState };
}
