import React, { createContext, useContext, useState, useCallback, useRef, useEffect } from 'react';
import {
  View,
  Text,
  StyleSheet,
  Animated,
  TouchableOpacity,
  Dimensions,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import {
  AppColors,
  BorderRadius,
  FontSizes,
  FontWeights,
  Spacing,
  Shadows,
} from '@/constants/theme';

const { width: SCREEN_WIDTH } = Dimensions.get('window');

type ToastType = 'success' | 'error' | 'info' | 'warning';

interface ToastConfig {
  type: ToastType;
  title: string;
  message?: string;
  duration?: number;
  action?: {
    label: string;
    onPress: () => void;
  };
}

interface ToastContextValue {
  show: (config: ToastConfig) => void;
  success: (title: string, message?: string) => void;
  error: (title: string, message?: string) => void;
  info: (title: string, message?: string) => void;
  hide: () => void;
}

const ToastContext = createContext<ToastContextValue | null>(null);

export function useToast() {
  const context = useContext(ToastContext);
  if (!context) {
    throw new Error('useToast must be used within a ToastProvider');
  }
  return context;
}

const toastConfig = {
  success: {
    icon: 'checkmark-circle' as const,
    color: AppColors.success,
    bgColor: AppColors.successLight,
  },
  error: {
    icon: 'close-circle' as const,
    color: AppColors.error,
    bgColor: AppColors.errorLight,
  },
  info: {
    icon: 'information-circle' as const,
    color: AppColors.info,
    bgColor: AppColors.infoLight,
  },
  warning: {
    icon: 'warning' as const,
    color: AppColors.warning,
    bgColor: AppColors.warningLight,
  },
};

interface ToastProviderProps {
  children: React.ReactNode;
}

export function ToastProvider({ children }: ToastProviderProps) {
  const insets = useSafeAreaInsets();
  const [visible, setVisible] = useState(false);
  const [config, setConfig] = useState<ToastConfig | null>(null);

  const translateY = useRef(new Animated.Value(-100)).current;
  const opacity = useRef(new Animated.Value(0)).current;
  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const hide = useCallback(() => {
    Animated.parallel([
      Animated.timing(translateY, {
        toValue: -100,
        duration: 250,
        useNativeDriver: true,
      }),
      Animated.timing(opacity, {
        toValue: 0,
        duration: 250,
        useNativeDriver: true,
      }),
    ]).start(() => {
      setVisible(false);
      setConfig(null);
    });
  }, [translateY, opacity]);

  const show = useCallback((newConfig: ToastConfig) => {
    // Clear any existing timeout
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
    }

    setConfig(newConfig);
    setVisible(true);

    // Animate in
    Animated.parallel([
      Animated.spring(translateY, {
        toValue: 0,
        tension: 80,
        friction: 10,
        useNativeDriver: true,
      }),
      Animated.timing(opacity, {
        toValue: 1,
        duration: 200,
        useNativeDriver: true,
      }),
    ]).start();

    // Auto hide
    const duration = newConfig.duration ?? 3000;
    timeoutRef.current = setTimeout(() => {
      hide();
    }, duration);
  }, [translateY, opacity, hide]);

  const success = useCallback((title: string, message?: string) => {
    show({ type: 'success', title, message });
  }, [show]);

  const error = useCallback((title: string, message?: string) => {
    show({ type: 'error', title, message });
  }, [show]);

  const info = useCallback((title: string, message?: string) => {
    show({ type: 'info', title, message });
  }, [show]);

  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);

  const typeConfig = config ? toastConfig[config.type] : toastConfig.info;

  return (
    <ToastContext.Provider value={{ show, success, error, info, hide }}>
      {children}
      {visible && config && (
        <Animated.View
          style={[
            styles.container,
            {
              top: insets.top + Spacing.sm,
              transform: [{ translateY }],
              opacity,
            },
          ]}
          pointerEvents="box-none"
        >
          <View style={styles.toast}>
            {/* Icon */}
            <View style={[styles.iconContainer, { backgroundColor: typeConfig.bgColor }]}>
              <Ionicons
                name={typeConfig.icon}
                size={24}
                color={typeConfig.color}
              />
            </View>

            {/* Content */}
            <View style={styles.content}>
              <Text style={styles.title}>{config.title}</Text>
              {config.message && (
                <Text style={styles.message} numberOfLines={2}>{config.message}</Text>
              )}
            </View>

            {/* Action or Close */}
            {config.action ? (
              <TouchableOpacity
                style={styles.actionButton}
                onPress={() => {
                  config.action?.onPress();
                  hide();
                }}
              >
                <Text style={styles.actionText}>{config.action.label}</Text>
              </TouchableOpacity>
            ) : (
              <TouchableOpacity style={styles.closeButton} onPress={hide}>
                <Ionicons name="close" size={20} color={AppColors.textMuted} />
              </TouchableOpacity>
            )}
          </View>
        </Animated.View>
      )}
    </ToastContext.Provider>
  );
}

// Legacy Toast component for backwards compatibility
interface LegacyToastProps {
  visible: boolean;
  message: string;
  icon?: keyof typeof Ionicons.glyphMap;
  duration?: number;
  onHide: () => void;
}

export function Toast({ visible, message, icon = 'checkmark-circle', duration = 2000, onHide }: LegacyToastProps) {
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const translateY = useRef(new Animated.Value(20)).current;

  useEffect(() => {
    if (visible) {
      Animated.parallel([
        Animated.timing(fadeAnim, {
          toValue: 1,
          duration: 200,
          useNativeDriver: true,
        }),
        Animated.timing(translateY, {
          toValue: 0,
          duration: 200,
          useNativeDriver: true,
        }),
      ]).start();

      const timer = setTimeout(() => {
        Animated.parallel([
          Animated.timing(fadeAnim, {
            toValue: 0,
            duration: 200,
            useNativeDriver: true,
          }),
          Animated.timing(translateY, {
            toValue: 20,
            duration: 200,
            useNativeDriver: true,
          }),
        ]).start(() => onHide());
      }, duration);

      return () => clearTimeout(timer);
    }
  }, [visible, duration, onHide]);

  if (!visible) return null;

  return (
    <Animated.View
      style={[
        styles.legacyContainer,
        {
          opacity: fadeAnim,
          transform: [{ translateY }],
        },
      ]}
    >
      <View style={styles.legacyIconContainer}>
        <Ionicons name={icon} size={20} color={AppColors.white} />
      </View>
      <Text style={styles.legacyMessage}>{message}</Text>
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  // New Toast Provider styles
  container: {
    position: 'absolute',
    left: Spacing.md,
    right: Spacing.md,
    zIndex: 9999,
  },
  toast: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: AppColors.surface,
    borderRadius: BorderRadius.xl,
    padding: Spacing.md,
    gap: Spacing.md,
    ...Shadows.lg,
    borderWidth: 1,
    borderColor: AppColors.borderLight,
  },
  iconContainer: {
    width: 44,
    height: 44,
    borderRadius: BorderRadius.lg,
    justifyContent: 'center',
    alignItems: 'center',
  },
  content: {
    flex: 1,
  },
  title: {
    fontSize: FontSizes.base,
    fontWeight: FontWeights.semibold,
    color: AppColors.textPrimary,
  },
  message: {
    fontSize: FontSizes.sm,
    color: AppColors.textSecondary,
    marginTop: 2,
  },
  actionButton: {
    paddingVertical: Spacing.sm,
    paddingHorizontal: Spacing.md,
    backgroundColor: AppColors.primaryLighter,
    borderRadius: BorderRadius.md,
  },
  actionText: {
    fontSize: FontSizes.sm,
    fontWeight: FontWeights.semibold,
    color: AppColors.primary,
  },
  closeButton: {
    width: 32,
    height: 32,
    borderRadius: BorderRadius.md,
    backgroundColor: AppColors.surfaceSecondary,
    justifyContent: 'center',
    alignItems: 'center',
  },
  // Legacy Toast styles
  legacyContainer: {
    position: 'absolute',
    bottom: 100,
    left: Spacing.xl,
    right: Spacing.xl,
    backgroundColor: AppColors.textPrimary,
    borderRadius: BorderRadius.lg,
    paddingVertical: Spacing.md,
    paddingHorizontal: Spacing.lg,
    flexDirection: 'row',
    alignItems: 'center',
    gap: Spacing.sm,
    ...Shadows.lg,
  },
  legacyIconContainer: {
    width: 28,
    height: 28,
    borderRadius: 14,
    backgroundColor: AppColors.success,
    justifyContent: 'center',
    alignItems: 'center',
  },
  legacyMessage: {
    flex: 1,
    fontSize: FontSizes.base,
    fontWeight: FontWeights.medium,
    color: AppColors.white,
  },
});
