import { useState, useEffect, useCallback, useRef } from 'react';
import { adaptBitrate, AdaptBitrateRequest } from '../services/bitrateService';
import { logger } from '@/utils/logger';

/**
 * Hook pour gérer l'adaptation de bitrate
 * T0351: Create Bitrate Adaptation Frontend Hook
 *
 * @param trackId - ID du track
 * @param currentBitrate - Bitrate actuel en kbps
 * @returns État et fonctions pour l'adaptation de bitrate
 */
export function useBitrateAdaptation(trackId: string, currentBitrate: number) {
  const [recommendedBitrate, setRecommendedBitrate] =
    useState<number>(currentBitrate);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<Error | null>(null);
  const [isAdapting, setIsAdapting] = useState<boolean>(false);

  // Ref pour éviter les mises à jour d'état si le composant est démonté
  const cancelledRef = useRef(false);

  // Mettre à jour le bitrate recommandé quand le bitrate actuel change
  useEffect(() => {
    setRecommendedBitrate(currentBitrate);
  }, [currentBitrate]);

  // Nettoyer la référence au démontage
  useEffect(() => {
    return () => {
      cancelledRef.current = true;
    };
  }, []);

  /**
   * Vérifie et adapte le bitrate en fonction des métriques
   * @param metrics - Métriques de streaming (bandwidth, buffer_level)
   */
  const checkAndAdapt = useCallback(
    async (metrics: Omit<AdaptBitrateRequest, 'current_bitrate'>) => {
      if (cancelledRef.current) {
        return;
      }

      try {
        setLoading(true);
        setError(null);
        setIsAdapting(true);

        const request: AdaptBitrateRequest = {
          current_bitrate: currentBitrate,
          ...metrics,
        };

        const response = await adaptBitrate(trackId, request);

        if (!cancelledRef.current) {
          setRecommendedBitrate(response.recommended_bitrate);
          setError(null);
        }
      } catch (err) {
        if (!cancelledRef.current) {
          const error =
            err instanceof Error ? err : new Error('Bitrate adaptation failed');
          setError(error);
          logger.error('Bitrate adaptation failed:', { error });
        }
      } finally {
        if (!cancelledRef.current) {
          setLoading(false);
          setIsAdapting(false);
        }
      }
    },
    [trackId, currentBitrate],
  );

  /**
   * Réinitialise l'état d'erreur
   */
  const clearError = useCallback(() => {
    setError(null);
  }, []);

  /**
   * Indique si le bitrate a changé
   */
  const hasBitrateChanged = recommendedBitrate !== currentBitrate;

  return {
    recommendedBitrate,
    loading,
    error,
    isAdapting,
    hasBitrateChanged,
    checkAndAdapt,
    clearError,
  };
}
