import { useCallback, useState } from 'react';
import { Platform } from 'react-native';
import Constants from 'expo-constants';
import { supabase } from '../lib/supabase';
import { protection } from '../lib/protection';

type SyncResult = { ok: boolean; count?: number; plan?: string; error?: string };

/**
 * Synct die binary Blocklist (`blocklist.bin`) vom Server in die App-Group.
 * Die NEFilter-Extension memory-mapped diese Datei — ohne Sync = leere
 * Blocklist = nichts wird geblockt.
 *
 * Triggers:
 *   - direkt nach activateUrlFilter() success
 *   - nach Domain-Add/-Submit/-Delete
 *   - bei App-Resume (in case Server-Updates kamen)
 *
 * Backend respondet 304 wenn ETag matched → kein Re-Download.
 *
 * iOS-Layer-2 / VIP: die kuratierte webContent-Domain-Liste wird über die
 * SEPARATE `syncWebContent`-Funktion gesynct — bewusst NICHT an `sync()`
 * gekoppelt. Layer 2 hängt an Family Controls, nicht am URL-Filter; der Sync
 * muss daher ungated laufen (auch wenn der URL-Filter aus ist).
 */
export function useBlocklistSync() {
  const [syncing, setSyncing] = useState(false);
  const [lastResult, setLastResult] = useState<SyncResult | null>(null);

  // iOS-Layer-2 / VIP-Liste: kuratierte webContent-Domain-Liste vom Backend
  // syncen. ENTKOPPELT vom Blocklist-Sync — Layer 2 hängt an Family Controls,
  // NICHT am URL-Filter, also ungated aufrufbar. Best-effort: schlägt es fehl,
  // greift nativ der gebündelte Fallback (loadWebContentDomains).
  const syncWebContent = useCallback(async (): Promise<void> => {
    if (Platform.OS !== 'ios') return;
    const baseURL = Constants.expoConfig?.extra?.apiUrl as string;
    const session = (await supabase.auth.getSession()).data.session;
    const authToken = session?.access_token;
    if (!baseURL || !authToken) {
      console.warn('[webcontent-sync] skipped — missing baseURL/token');
      return;
    }
    try {
      const res = await protection.syncWebContentDomains({ baseURL, authToken });
      console.log('[webcontent-sync] ok:', JSON.stringify(res));
    } catch (e: any) {
      console.warn(
        '[webcontent-sync] failed (bundled fallback active):',
        e?.message ?? e,
      );
    }
  }, []);

  const sync = useCallback(async (): Promise<SyncResult> => {
    if (syncing) return { ok: false, error: 'already_syncing' };
    setSyncing(true);
    try {
      const baseURL = Constants.expoConfig?.extra?.apiUrl as string;
      const session = (await supabase.auth.getSession()).data.session;
      const authToken = session?.access_token;

      if (!baseURL || !authToken) {
        const result = { ok: false, error: 'missing_baseURL_or_token' };
        setLastResult(result);
        return result;
      }

      const res = await protection.syncBlocklist({ baseURL, authToken });
      const result = { ok: true, count: res.count, plan: res.plan };
      setLastResult(result);
      console.log('[blocklist-sync] ok:', res);
      return result;
    } catch (e: any) {
      const result = { ok: false, error: e?.message ?? 'sync_failed' };
      setLastResult(result);
      console.error('[blocklist-sync] failed:', e);
      return result;
    } finally {
      setSyncing(false);
    }
  }, [syncing]);

  return { sync, syncWebContent, syncing, lastResult };
}
