'use client';

import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { InstallationRepository } from '@/repositories/teltoinstall/_index';
import { ProvisioningStatus } from '@/models/teltoinstall/_index';
import { apiErrorMessage } from '@/utils/teltoinstall/_index';

const POLL_INTERVAL_MS = 4000;

/**
 * Suit le provisionnement du boîtier (task Teltonika + device Flespi), joué en
 * tâche de fond après l'étape « Boîtier ». Interroge le serveur immédiatement
 * puis en polling tant que c'est en cours (`pending`/`processing`), et s'arrête
 * dès que c'est terminé (`provisioned`/`failed`).
 *
 * Expose `configuring` = configuration encore en cours : l'étape « Validation »
 * s'en sert pour désactiver le test de connexion tant que ce n'est pas prêt.
 * En échec, `error` porte la cause et `retry()` relance la configuration, puis
 * le polling reprend.
 */
export function useProvisioningStatus(installationId: number | null) {
  const { t } = useTranslation();
  const [status, setStatus] = useState<ProvisioningStatus | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [retrying, setRetrying] = useState(false);
  // Incrémenté à chaque relance : relance l'effet de polling.
  const [round, setRound] = useState(0);

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

    let cancelled = false;
    let timer: ReturnType<typeof setTimeout>;

    async function poll() {
      try {
        const next = await InstallationRepository.provisioningStatus(installationId as number);
        if (cancelled) return;
        setStatus(next.status);
        setError(next.error);
        // On ne continue à interroger que tant que la config est en cours.
        if (next.status === 'pending' || next.status === 'processing') {
          timer = setTimeout(poll, POLL_INTERVAL_MS);
        }
      } catch {
        // Erreur réseau : on retente au prochain tick plutôt que de rester figé.
        if (!cancelled) timer = setTimeout(poll, POLL_INTERVAL_MS);
      }
    }

    poll();

    return () => {
      cancelled = true;
      clearTimeout(timer);
    };
  }, [installationId, round]);

  const retry = useCallback(async () => {
    if (!installationId) return;
    setRetrying(true);
    try {
      const next = await InstallationRepository.retryProvisioning(installationId);
      setStatus(next.status);
      setError(next.error);
    } catch (err) {
      setError(apiErrorMessage(err, t('errors.generic')));
    } finally {
      setRetrying(false);
      setRound((r) => r + 1);
    }
  }, [installationId, t]);

  return {
    status,
    error,
    configuring: status === 'pending' || status === 'processing',
    failed: status === 'failed',
    retry,
    retrying,
  };
}
