'use client';

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useRef,
  useState,
  type ReactNode,
} from 'react';
import { subscribeBroadcast, type SyncMessage } from '@/lib/queue/broadcast';
import { runSync } from '@/lib/queue/sync';
import { db } from '@/lib/queue/db';

interface SyncState {
  pendingCount: number;
  deadLetterCount: number;
}

const SyncCtx = createContext<SyncState>({ pendingCount: 0, deadLetterCount: 0 });
export const useSyncState = () => useContext(SyncCtx);

export function SyncProvider({ children }: { children: ReactNode }) {
  const [state, setState] = useState<SyncState>({ pendingCount: 0, deadLetterCount: 0 });
  const [failedIds, setFailedIds] = useState<string[]>([]);
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const refreshCounts = useCallback(async () => {
    const [p, d] = await Promise.all([db.pending.count(), db.deadLetters.count()]);
    setState({ pendingCount: p, deadLetterCount: d });
  }, []);

  const sync = useCallback(async () => {
    await runSync();
    await refreshCounts();
  }, [refreshCounts]);

  useEffect(() => {
    refreshCounts();

    const unsub = subscribeBroadcast(async (msg: SyncMessage) => {
      await refreshCounts();
      if (msg.type === 'dead-letter') {
        setFailedIds((prev) => [...prev, msg.clientRequestId]);
      }
    });

    const onOnline = () => sync();
    const onVisible = () => {
      if (document.visibilityState === 'visible' && navigator.onLine) sync();
    };

    window.addEventListener('online', onOnline);
    document.addEventListener('visibilitychange', onVisible);

    timerRef.current = setInterval(() => {
      if (navigator.onLine) sync();
    }, 10_000);

    if ('serviceWorker' in navigator && 'SyncManager' in window) {
      navigator.serviceWorker.ready
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        .then((reg) => (reg as any).sync.register('mai-call-sync'))
        .catch(() => {/* not supported or permission denied */});
    }

    if (navigator.onLine) sync();

    return () => {
      unsub();
      window.removeEventListener('online', onOnline);
      document.removeEventListener('visibilitychange', onVisible);
      if (timerRef.current) clearInterval(timerRef.current);
    };
  }, [sync, refreshCounts]);

  return (
    <SyncCtx.Provider value={state}>
      {children}
      {failedIds.length > 0 && (
        <div className="fixed bottom-4 left-4 right-4 z-50 flex flex-col gap-2">
          {failedIds.map((id) => (
            <div
              key={id}
              className="flex items-center justify-between rounded-lg bg-destructive px-4 py-3 text-sm text-destructive-foreground shadow-lg"
            >
              <span>Pedido {id.slice(0, 8)}… falhou — contacta o supervisor.</span>
              <button
                onClick={() => setFailedIds((prev) => prev.filter((x) => x !== id))}
                className="ml-4 shrink-0 opacity-80 hover:opacity-100"
                aria-label="Fechar"
              >
                ✕
              </button>
            </div>
          ))}
        </div>
      )}
    </SyncCtx.Provider>
  );
}
