import React, { useState, useEffect, useRef } from 'react';
import { StyleSheet, View, Text, TouchableOpacity, Modal, Animated, Dimensions, Platform, Image } from 'react-native';
import { X, ChevronRight } from 'lucide-react-native';
import { LinearGradient } from 'expo-linear-gradient';
import { useTheme } from '@/context/ThemeContext';

interface TutorialStep {
  targetRef: React.RefObject<View>;
  title: string;
  message: string;
  icon?: React.ReactNode;
}

interface TutorialOverlayProps {
  visible: boolean;
  steps: TutorialStep[];
  onComplete: () => void;
}

export default function TutorialOverlay({ visible, steps, onComplete }: TutorialOverlayProps) {
  const [currentStep, setCurrentStep] = useState(0);
  const [targetMeasurements, setTargetMeasurements] = useState({ x: 0, y: 0, width: 0, height: 0 });
  const [measurementAttempts, setMeasurementAttempts] = useState(0);
  const [measurementSuccess, setMeasurementSuccess] = useState(false);
  
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const scaleAnim = useRef(new Animated.Value(0.95)).current;
  const slideAnim = useRef(new Animated.Value(Platform.OS === 'web' ? 0 : 10)).current;
  
  const windowDimensions = Dimensions.get('window');
  const isSmallScreen = windowDimensions.width < 360;
  const isShortScreen = windowDimensions.height < 700;
  
  const { theme, colors: themeColors } = useTheme();
  
  // Reset state when visibility changes
  useEffect(() => {
    if (visible) {
      setCurrentStep(0);
      setMeasurementAttempts(0);
      setMeasurementSuccess(false);
      
      // Animate in
      Animated.parallel([
        Animated.timing(fadeAnim, {
          toValue: 1,
          duration: 200, // Faster animation
          useNativeDriver: Platform.OS !== 'web',
        }),
        Animated.timing(scaleAnim, {
          toValue: 1,
          duration: 200, // Faster animation
          useNativeDriver: Platform.OS !== 'web',
        }),
        Animated.timing(slideAnim, {
          toValue: 0,
          duration: 200, // Faster animation
          useNativeDriver: Platform.OS !== 'web',
        }),
      ]).start();
      
      // Start measuring immediately
      setTimeout(() => {
        measureTarget();
      }, 100);
    } else {
      // Reset animations
      fadeAnim.setValue(0);
      scaleAnim.setValue(0.95);
      slideAnim.setValue(Platform.OS === 'web' ? 0 : 10);
    }
    
    // Cleanup animations on unmount
    return () => {
      fadeAnim.stopAnimation();
      scaleAnim.stopAnimation();
      slideAnim.stopAnimation();
    };
  }, [visible]);
  
  // Measure target element position
  const measureTarget = () => {
    try {
      if (!visible || !steps[currentStep]?.targetRef?.current) {
        console.log("Target ref is null, unavailable, or tutorial not visible");
        
        // If we've tried too many times, use fallback values
        if (measurementAttempts > 2) {
          console.log("Using fallback measurements");
          
          // Use different fallback positions based on step number
          // This ensures tooltips don't all stack in the same place
          const yOffset = 100 + (currentStep * 80);
          
          setTargetMeasurements({
            x: windowDimensions.width / 2 - 75,
            y: yOffset,
            width: 150,
            height: 50
          });
          setMeasurementSuccess(true);
        } else {
          // Try again after a short delay
          setTimeout(() => {
            setMeasurementAttempts(prev => prev + 1);
            measureTarget();
          }, 150);
        }
        return;
      }
      
      steps[currentStep].targetRef.current.measureInWindow((x, y, width, height) => {
        if (width === 0 && height === 0) {
          // Invalid measurement, try again
          if (measurementAttempts < 3) {
            setTimeout(() => {
              setMeasurementAttempts(prev => prev + 1);
              measureTarget();
            }, 150);
          } else {
            // Use fallback values after too many attempts
            const yOffset = 100 + (currentStep * 80);
            
            setTargetMeasurements({
              x: windowDimensions.width / 2 - 75,
              y: yOffset,
              width: 150,
              height: 50
            });
            setMeasurementSuccess(true);
          }
        } else {
          // Valid measurement
          console.log(`Measured element: x=${x}, y=${y}, width=${width}, height=${height}`);
          setTargetMeasurements({ x, y, width, height });
          setMeasurementSuccess(true);
        }
      });
    } catch (error) {
      console.error("Error measuring target:", error);
      // Use fallback values on error
      const yOffset = 100 + (currentStep * 80);
      
      setTargetMeasurements({
        x: windowDimensions.width / 2 - 75,
        y: yOffset,
        width: 150,
        height: 50
      });
      setMeasurementSuccess(true);
    }
  };
  
  // Re-measure when step changes
  useEffect(() => {
    if (visible) {
      setMeasurementAttempts(0);
      setMeasurementSuccess(false);
      
      // Small delay to ensure UI has updated
      setTimeout(() => {
        measureTarget();
      }, 100);
    }
  }, [currentStep, visible]);
  
  // Handle next step
  const handleNext = () => {
    try {
      if (currentStep < steps.length - 1) {
        // Animate out current step
        Animated.parallel([
          Animated.timing(fadeAnim, {
            toValue: 0,
            duration: 100,
            useNativeDriver: Platform.OS !== 'web',
          }),
          Animated.timing(scaleAnim, {
            toValue: 0.95,
            duration: 100,
            useNativeDriver: Platform.OS !== 'web',
          }),
        ]).start(() => {
          setCurrentStep(prev => prev + 1);
          setMeasurementAttempts(0);
          setMeasurementSuccess(false);
          
          // Animate in next step
          Animated.parallel([
            Animated.timing(fadeAnim, {
              toValue: 1,
              duration: 200,
              useNativeDriver: Platform.OS !== 'web',
            }),
            Animated.timing(scaleAnim, {
              toValue: 1,
              duration: 200,
              useNativeDriver: Platform.OS !== 'web',
            }),
          ]).start();
        });
      } else {
        handleComplete();
      }
    } catch (error) {
      console.error("Error in handleNext:", error);
      handleComplete(); // Safely exit on error
    }
  };
  
  // Handle tutorial completion
  const handleComplete = () => {
    try {
      // Animate out
      Animated.parallel([
        Animated.timing(fadeAnim, {
          toValue: 0,
          duration: 150,
          useNativeDriver: Platform.OS !== 'web',
        }),
        Animated.timing(scaleAnim, {
          toValue: 0.95,
          duration: 150,
          useNativeDriver: Platform.OS !== 'web',
        }),
        Animated.timing(slideAnim, {
          toValue: Platform.OS === 'web' ? 0 : 10,
          duration: 150,
          useNativeDriver: Platform.OS !== 'web',
        }),
      ]).start(() => {
        onComplete();
      });
    } catch (error) {
      console.error("Error in handleComplete:", error);
      onComplete(); // Ensure we still complete even on error
    }
  };
  
  // Calculate tooltip position
  const getTooltipPosition = () => {
    try {
      const { x, y, width, height } = targetMeasurements;
      
      // Adjust tooltip size based on screen size
      const tooltipWidth = isSmallScreen ? 220 : 240; // Smaller tooltip
      const tooltipHeight = isShortScreen ? 120 : 140; // Smaller tooltip
      const margin = 12; // Smaller margin
      
      // Default position (below target)
      let tooltipX = x + (width / 2) - (tooltipWidth / 2);
      let tooltipY = y + height + margin;
      let arrowPosition = 'top';
      
      // Ensure tooltip is within screen bounds
      if (tooltipX < margin) tooltipX = margin;
      if (tooltipX + tooltipWidth > windowDimensions.width - margin) {
        tooltipX = windowDimensions.width - tooltipWidth - margin;
      }
      
      // If tooltip would go off bottom of screen, place it above target
      if (tooltipY + tooltipHeight > windowDimensions.height - 60) {
        tooltipY = y - tooltipHeight - margin;
        arrowPosition = 'bottom';
      }
      
      // If tooltip would go off top of screen, place it below target anyway
      if (tooltipY < 50) {
        tooltipY = y + height + margin;
        arrowPosition = 'top';
        
        // If it still doesn't fit, center it on screen
        if (tooltipY + tooltipHeight > windowDimensions.height - 60) {
          tooltipY = windowDimensions.height / 2 - tooltipHeight / 2;
          arrowPosition = 'none'; // Hide arrow when centered
        }
      }
      
      return { tooltipX, tooltipY, arrowPosition };
    } catch (error) {
      console.error("Error calculating tooltip position:", error);
      // Fallback to center position
      return {
        tooltipX: windowDimensions.width / 2 - (isSmallScreen ? 110 : 120),
        tooltipY: windowDimensions.height / 2 - (isShortScreen ? 60 : 70),
        arrowPosition: 'none'
      };
    }
  };
  
  if (!visible) return null;
  
  const { tooltipX, tooltipY, arrowPosition } = getTooltipPosition();
  const currentStepData = steps[currentStep];
  
  return (
    <Modal
      transparent={true}
      visible={visible}
      animationType="none"
      onRequestClose={handleComplete}
    >
      <View style={styles.overlay}>
        {/* Highlight around target element */}
        {measurementSuccess && (
          <View
            style={[
              styles.highlight,
              {
                left: targetMeasurements.x - 4, // Thinner border
                top: targetMeasurements.y - 4, // Thinner border
                width: targetMeasurements.width + 8, // Thinner border
                height: targetMeasurements.height + 8, // Thinner border
                borderColor: themeColors.primary,
                backgroundColor: `${themeColors.primary}10`, // More subtle highlight
              },
            ]}
          />
        )}
        
        {/* Tooltip */}
        {measurementSuccess && (
          <Animated.View
            style={[
              styles.tooltip,
              {
                left: tooltipX,
                top: tooltipY,
                width: isSmallScreen ? 220 : 240, // Smaller tooltip
                height: isShortScreen ? 120 : 140, // Smaller tooltip
                opacity: fadeAnim,
                backgroundColor: themeColors.backgroundSecondary,
                borderColor: `${themeColors.primary}30`,
                transform: Platform.OS === 'web' 
                  ? [] 
                  : [{ scale: scaleAnim }, { translateY: slideAnim }]
              },
            ]}
          >
            {theme === 'dark' && (
              <LinearGradient
                colors={[`${themeColors.primary}15`, `${themeColors.primary}05`]}
                style={styles.tooltipGradient}
              />
            )}
            
            {/* Arrow pointing to target */}
            {arrowPosition !== 'none' && (
              <View
                style={[
                  styles.tooltipArrow,
                  arrowPosition === 'top' ? styles.tooltipArrowTop : styles.tooltipArrowBottom,
                  {
                    backgroundColor: themeColors.backgroundSecondary,
                    borderColor: `${themeColors.primary}30`,
                  }
                ]}
              />
            )}
            
            {/* Close button */}
            <TouchableOpacity 
              style={styles.closeButton} 
              onPress={handleComplete}
              hitSlop={{ top: 15, right: 15, bottom: 15, left: 15 }} // Larger hit area
            >
              <X size={16} color={themeColors.textSecondary} />
            </TouchableOpacity>
            
            {/* Content */}
            <View style={styles.tooltipContent}>
              {currentStepData.icon && (
                <View style={styles.iconContainer}>
                  {currentStepData.icon}
                </View>
              )}
              
              <Text style={[styles.tooltipTitle, { color: themeColors.text }]}>
                {currentStepData.title}
              </Text>
              
              <Text 
                style={[
                  styles.tooltipMessage, 
                  { 
                    color: themeColors.textSecondary,
                    fontSize: isSmallScreen ? 12 : 13,
                  }
                ]}
                numberOfLines={isShortScreen ? 2 : 3}
              >
                {currentStepData.message}
              </Text>
            </View>
            
            {/* Navigation */}
            <View style={styles.tooltipFooter}>
              <Text style={[styles.stepIndicator, { color: themeColors.textSecondary }]}>
                {currentStep + 1}/{steps.length}
              </Text>
              
              <TouchableOpacity 
                style={[
                  styles.nextButton, 
                  { backgroundColor: `${themeColors.primary}15` }
                ]} 
                onPress={handleNext}
              >
                <Text style={[styles.nextButtonText, { color: themeColors.primary }]}>
                  {currentStep < steps.length - 1 ? 'Next' : 'Got it'}
                </Text>
                <ChevronRight size={14} color={themeColors.primary} />
              </TouchableOpacity>
            </View>
          </Animated.View>
        )}
      </View>
    </Modal>
  );
}

const styles = StyleSheet.create({
  overlay: {
    flex: 1,
    backgroundColor: 'rgba(0, 0, 0, 0.7)', // Darker overlay for better contrast
  },
  highlight: {
    position: 'absolute',
    borderRadius: 4, // Smaller radius
    borderWidth: 1.5, // Thinner border
    zIndex: 10,
  },
  tooltip: {
    position: 'absolute',
    borderRadius: 8, // Smaller radius
    padding: 10, // Less padding
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.2,
    shadowRadius: 4,
    elevation: 6,
    overflow: 'visible',
    borderWidth: 1,
    zIndex: 20,
  },
  tooltipGradient: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    borderRadius: 8,
  },
  tooltipArrow: {
    position: 'absolute',
    width: 10, // Smaller arrow
    height: 10, // Smaller arrow
    transform: [{ rotate: '45deg' }],
    zIndex: -1,
  },
  tooltipArrowTop: {
    top: -5, // Position closer to tooltip
    left: '50%',
    marginLeft: -5,
    borderBottomWidth: 0,
    borderRightWidth: 0,
  },
  tooltipArrowBottom: {
    bottom: -5, // Position closer to tooltip
    left: '50%',
    marginLeft: -5,
    borderTopWidth: 0,
    borderLeftWidth: 0,
  },
  closeButton: {
    position: 'absolute',
    top: 6,
    right: 6,
    padding: 2,
    zIndex: 10,
  },
  tooltipContent: {
    marginTop: 2, // Less margin
    marginBottom: 6, // Less margin
  },
  iconContainer: {
    alignItems: 'center',
    marginBottom: 6, // Less margin
  },
  tooltipTitle: {
    fontSize: 15, // Smaller font
    fontWeight: 'bold',
    marginBottom: 3, // Less margin
    textAlign: 'center',
  },
  tooltipMessage: {
    lineHeight: 17, // Tighter line height
    textAlign: 'center',
  },
  tooltipFooter: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginTop: 'auto',
  },
  stepIndicator: {
    fontSize: 12,
  },
  nextButton: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingVertical: 4, // Less padding
    paddingHorizontal: 8, // Less padding
    borderRadius: 6,
  },
  nextButtonText: {
    fontSize: 13,
    fontWeight: '500',
    marginRight: 2,
  },
});