import { useEffect, useState, useRef } from 'react';
import { SyncClient } from '../services/syncClient';
import { audioPlayerService } from '../services/playerService';
import { TokenStorage } from '@/services/tokenStorage';
import { logger } from '@/utils/logger';

export function useStreamSync(params: {
  sessionId: string | null;
  trackId: string | null;
}) {
  const [isSynced, setIsSynced] = useState(false);
  const syncClientRef = useRef<SyncClient | null>(null);

  // Gets access token from TokenStorage
  const accessToken = TokenStorage.getAccessToken();

  useEffect(() => {
    // Only connect if we have a valid session and token
    if (!params.sessionId || !params.trackId || !accessToken) {
      if (syncClientRef.current) {
        syncClientRef.current.disconnect();
        syncClientRef.current = null;
        setIsSynced(false);
      }
      return;
    }

    // Prevent reconnecting if nothing changed
    // NOTE: In a real app we might want deeper comparison or memoized params

    // Initialize SyncClient
    const client = new SyncClient({
      token: accessToken,
      sessionId: params.sessionId,
      trackId: params.trackId,
      getPlayerState: () => {
        return {
          playbackPositionMs: audioPlayerService.getCurrentTime() * 1000,
          clientTimestampMs: Date.now(),
        };
      },
      applyAdjustment: (driftMs) => {
        // Simple strategy:
        // if drift > 40ms, simple seek
        // if drift small, maybe nothing or playbackRate (not implemented yet)

        // This is where "smart" logic goes.
        // For now: coarse correction.
        const DRIFT_THRESHOLD_MS = 100; // 100ms tolerance

        if (Math.abs(driftMs) > DRIFT_THRESHOLD_MS) {
          // Negative drift = client is BEHIND master -> we need to seek FORWARD
          // Positive drift = client is AHEAD master -> we need to seek BACKWARD
          // Wait, drift = Client - Master
          // if Client = 10100, Master = 10000, Drift = 100 (Ahead) -> Seek to Current - Drift
          // if Client = 9900, Master = 10000, Drift = -100 (Behind) -> Seek to Current - Drift

          const currentSec = audioPlayerService.getCurrentTime();
          const correctionSec = driftMs / 1000;
          // Target = Current - Correction
          // Example: Ahead (100ms), we subtract 0.1s. Correct.
          // Example: Behind (-100ms), we subtract -0.1s (add). Correct.

          const targetTime = currentSec - correctionSec;

          // Stream sync correction - logging removed for production
          // Debug info available via onDebug callback if needed
          audioPlayerService.seek(targetTime);
        }
      },
      onStable: () => {
        setIsSynced(true);
      },
      onDebug: (_msg, _data) => {
        if (import.meta.env.DEV) {
          // console.debug(`[useStreamSync] ${_msg}`, _data);
        }
      },
      onError: (err) => {
        logger.error('[useStreamSync] Error:', { error: err });
        setIsSynced(false);
      },
    });

    client.connect();
    syncClientRef.current = client;

    return () => {
      client.disconnect();
      syncClientRef.current = null;
      setIsSynced(false);
    };
  }, [params.sessionId, params.trackId, accessToken]);

  return { isSynced };
}
