import { useState, useEffect } from 'react';
import { api } from '../api/client';

function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
  const base64  = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
  const raw     = window.atob(base64);
  return Uint8Array.from([...raw].map((c) => c.charCodeAt(0)));
}

/**
 * Hook managing the Web Push subscription lifecycle for a given coastalPointId.
 * Returns { supported, subscribed, loading, error, toggle }
 */
export default function usePushSubscription(coastalPointId) {
  const [supported,  setSupported]  = useState(false);
  const [subscribed, setSubscribed] = useState(false);
  const [loading,    setLoading]    = useState(false);
  const [error,      setError]      = useState(null);

  useEffect(() => {
    setSupported('serviceWorker' in navigator && 'PushManager' in window);
  }, []);

  useEffect(() => {
    if (!supported) return;

    navigator.serviceWorker.ready.then((reg) =>
      reg.pushManager.getSubscription()
    ).then((sub) => {
      setSubscribed(sub !== null);
    }).catch(() => {});
  }, [supported]);

  const toggle = async () => {
    if (!supported || loading) return;
    setLoading(true);
    setError(null);

    try {
      const reg = await navigator.serviceWorker.ready;
      const existingSub = await reg.pushManager.getSubscription();

      if (existingSub) {
        await api.push.unsubscribe(existingSub.endpoint).catch(() => {});
        await existingSub.unsubscribe();
        setSubscribed(false);
      } else {
        const { publicKey } = await api.push.vapidKey();
        const sub = await reg.pushManager.subscribe({
          userVisibleOnly:      true,
          applicationServerKey: urlBase64ToUint8Array(publicKey),
        });
        const json = sub.toJSON();
        await api.push.subscribe({
          endpoint:      json.endpoint,
          keys:          json.keys,
          coastalPointId,
        });
        setSubscribed(true);
      }
    } catch (e) {
      setError(e.message ?? 'Erreur abonnement push');
    } finally {
      setLoading(false);
    }
  };

  return { supported, subscribed, loading, error, toggle };
}
