import { useState, useCallback, useEffect } from 'react';
import { driver, Driver } from 'driver.js';
import { useNavigate } from 'react-router-dom';
import { ROUTES } from '../../../router/routes.config';
import { getDriverConfig } from '../config/driver-config';
import { getDemoTourSteps, getMobileTourSteps } from '../config/tour-steps';
import { getTourState, saveTourState, clearTourStartPending, clearTourState } from '../utils/tour-state';
import { trackTourEvent } from '../utils/tour-analytics';
import '../styles.css';

export const useDemoTour = () => {
  const navigate = useNavigate();
  const [tourActive, setTourActive] = useState(false);
  const [driverInstance, setDriverInstance] = useState<Driver | null>(null);

  const isMobile = window.innerWidth < 768;

  const handleTourDestroy = useCallback(() => {
    const state = getTourState();
    const currentStep = driverInstance?.getActiveIndex() || 0;

    if (state && !state.completed) {
      saveTourState({
        currentStep,
        dismissed: true,
      });

      trackTourEvent({
        event: 'tour_dismissed',
        step: currentStep,
        timestamp: Date.now(),
      });
    }

    setTourActive(false);
    clearTourStartPending();
  }, [driverInstance]);

  const handleStepComplete = useCallback((stepIndex: number) => {
    saveTourState({
      currentStep: stepIndex + 1,
    });

    trackTourEvent({
      event: 'tour_step_completed',
      step: stepIndex,
      timestamp: Date.now(),
    });
  }, []);

  const handleTourComplete = useCallback(() => {
    saveTourState({
      completed: true,
      currentStep: 0,
    });

    trackTourEvent({
      event: 'tour_completed',
      timestamp: Date.now(),
    });

    setTourActive(false);
    clearTourStartPending();

    setTimeout(() => {
      trackTourEvent({
        event: 'conversion_cta_clicked',
        timestamp: Date.now(),
      });
      navigate('/register?from=demo_tour');
    }, 500);
  }, [navigate]);

  const startTour = useCallback((fromStep: number = 0, retryCount: number = 0) => {
    console.log('[useDemoTour] startTour called with fromStep:', fromStep, 'retry:', retryCount);

    // Check if we're already on the dashboard
    const currentPath = window.location.pathname;
    if (currentPath !== ROUTES.DASHBOARD) {
      console.log('[useDemoTour] Not on dashboard, navigating to:', ROUTES.DASHBOARD);
      // Store tour intent in sessionStorage before navigation
      sessionStorage.setItem('demo_tour_should_start', 'true');
      sessionStorage.setItem('demo_tour_start_step', fromStep.toString());

      // Navigate to dashboard
      navigate(ROUTES.DASHBOARD);
      return;
    }

    const steps = isMobile ? getMobileTourSteps() : getDemoTourSteps();
    console.log('[useDemoTour] Using', isMobile ? 'mobile' : 'desktop', 'steps, total:', steps.length);

    // Check if critical tour elements exist (only if we're on the dashboard)
    if (currentPath === ROUTES.DASHBOARD) {
      // Validate critical dashboard elements
      const criticalSelectors = [
        '[data-tour="demo-banner"]',
        '[data-tour="dashboard-stats"]'
      ];

      let missingElement = null;
      for (const selector of criticalSelectors) {
        const el = document.querySelector(selector);
        if (!el) {
          missingElement = selector;
          break;
        }
      }

      if (missingElement) {
        // Retry up to 5 times with exponential backoff
        if (retryCount < 5) {
          const delay = Math.min(500 * Math.pow(1.5, retryCount), 3000);
          console.warn(`[useDemoTour] Critical tour element "${missingElement}" not found! Retrying in ${delay}ms (attempt ${retryCount + 1}/5)...`);
          setTimeout(() => startTour(fromStep, retryCount + 1), delay);
          return;
        } else {
          console.error(`[useDemoTour] Failed to find critical element "${missingElement}" after 5 retries. Tour cannot start.`);
          // Clear the tour start flag to prevent infinite retry loops
          sessionStorage.removeItem('demo_tour_should_start');
          sessionStorage.removeItem('demo_tour_start_step');
          clearTourStartPending();
          return;
        }
      }

      console.log('[useDemoTour] All critical tour elements found, starting tour...');
    }

    const config = getDriverConfig(handleStepComplete);

    const driverObj = driver({
      ...config,
      onDestroyed: (element, step, options) => {
        const activeIndex = options.state?.activeIndex || 0;
        const isLastStep = activeIndex === steps.length - 1;

        console.log('[useDemoTour] Tour destroyed, activeIndex:', activeIndex, 'isLastStep:', isLastStep);

        if (isLastStep) {
          handleTourComplete();
        } else {
          handleTourDestroy();
        }
      },
    });

    driverObj.setSteps(steps);
    setDriverInstance(driverObj);

    console.log('[useDemoTour] Driver instance created, starting tour...');

    if (fromStep > 0 && fromStep < steps.length) {
      driverObj.drive(fromStep);
    } else {
      driverObj.drive();
    }

    setTourActive(true);

    trackTourEvent({
      event: 'tour_started',
      timestamp: Date.now(),
    });

    saveTourState({
      currentStep: fromStep,
      completed: false,
      dismissed: false,
    });

    clearTourStartPending();
  }, [isMobile, handleTourDestroy, handleStepComplete, handleTourComplete, navigate]);

  const resumeTour = useCallback(() => {
    const state = getTourState();
    if (state && state.currentStep > 0) {
      startTour(state.currentStep);
    } else {
      startTour();
    }
  }, [startTour]);

  const resetTour = useCallback(() => {
    clearTourState();
    if (driverInstance) {
      driverInstance.destroy();
      setDriverInstance(null);
    }
    setTourActive(false);
  }, [driverInstance]);

  useEffect(() => {
    return () => {
      if (driverInstance) {
        driverInstance.destroy();
      }
    };
  }, [driverInstance]);

  return {
    startTour,
    resumeTour,
    resetTour,
    tourActive,
    tourState: getTourState(),
  };
};
