/**
 * ErrorToast - Animated toast notification for errors
 *
 * Features:
 * - Slides in from top
 * - Auto-dismiss for non-critical errors
 * - Retry and dismiss actions
 * - Severity-based styling
 */

import React, { useEffect, useRef } from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
  Animated,
  Platform,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { AppError, ErrorSeverity } from '@/types/errors';

interface ErrorToastProps {
  error: AppError & { onRetry?: () => void };
  onDismiss: () => void;
  visible: boolean;
}

// Severity colors
const severityColors: Record<ErrorSeverity, { bg: string; border: string; icon: string }> = {
  critical: { bg: '#FEE2E2', border: '#EF4444', icon: '#DC2626' },
  error: { bg: '#FEE2E2', border: '#EF4444', icon: '#DC2626' },
  warning: { bg: '#FEF3C7', border: '#F59E0B', icon: '#D97706' },
  info: { bg: '#DBEAFE', border: '#3B82F6', icon: '#2563EB' },
};

// Severity icons
const severityIcons: Record<ErrorSeverity, keyof typeof Ionicons.glyphMap> = {
  critical: 'alert-circle',
  error: 'close-circle',
  warning: 'warning',
  info: 'information-circle',
};

export function ErrorToast({ error, onDismiss, visible }: ErrorToastProps) {
  const insets = useSafeAreaInsets();
  const slideAnim = useRef(new Animated.Value(-200)).current;
  const opacityAnim = useRef(new Animated.Value(0)).current;

  const colors = severityColors[error.severity];
  const icon = severityIcons[error.severity];

  useEffect(() => {
    if (visible) {
      // Slide in
      Animated.parallel([
        Animated.spring(slideAnim, {
          toValue: 0,
          useNativeDriver: true,
          tension: 50,
          friction: 8,
        }),
        Animated.timing(opacityAnim, {
          toValue: 1,
          duration: 200,
          useNativeDriver: true,
        }),
      ]).start();
    } else {
      // Slide out
      Animated.parallel([
        Animated.timing(slideAnim, {
          toValue: -200,
          duration: 200,
          useNativeDriver: true,
        }),
        Animated.timing(opacityAnim, {
          toValue: 0,
          duration: 200,
          useNativeDriver: true,
        }),
      ]).start();
    }
  }, [visible, slideAnim, opacityAnim]);

  // Component always renders when not visible - animations handle visibility
  if (!visible) {
    // We still render to allow the slide-out animation to complete
  }

  return (
    <Animated.View
      style={[
        styles.container,
        {
          paddingTop: insets.top + 8,
          transform: [{ translateY: slideAnim }],
          opacity: opacityAnim,
        },
      ]}
      pointerEvents="box-none"
    >
      <View
        style={[
          styles.toast,
          {
            backgroundColor: colors.bg,
            borderColor: colors.border,
          },
        ]}
      >
        {/* Icon */}
        <View style={styles.iconContainer}>
          <Ionicons name={icon} size={24} color={colors.icon} />
        </View>

        {/* Content */}
        <View style={styles.content}>
          <Text style={styles.message} numberOfLines={2}>
            {error.userMessage}
          </Text>
          {error.actionHint && (
            <Text style={styles.hint} numberOfLines={1}>
              {error.actionHint}
            </Text>
          )}
        </View>

        {/* Actions */}
        <View style={styles.actions}>
          {error.retry.isRetryable && error.onRetry && (
            <TouchableOpacity
              style={styles.retryButton}
              onPress={() => {
                onDismiss();
                error.onRetry?.();
              }}
              hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
            >
              <Ionicons name="refresh" size={20} color={colors.icon} />
            </TouchableOpacity>
          )}
          <TouchableOpacity
            style={styles.dismissButton}
            onPress={onDismiss}
            hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
          >
            <Ionicons name="close" size={20} color="#6B7280" />
          </TouchableOpacity>
        </View>
      </View>
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    zIndex: 9999,
    paddingHorizontal: 16,
  },
  toast: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 12,
    borderRadius: 12,
    borderWidth: 1,
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 4 },
        shadowOpacity: 0.15,
        shadowRadius: 8,
      },
      android: {
        elevation: 6,
      },
    }),
  },
  iconContainer: {
    marginRight: 12,
  },
  content: {
    flex: 1,
    marginRight: 8,
  },
  message: {
    fontSize: 14,
    fontWeight: '600',
    color: '#1F2937',
    lineHeight: 20,
  },
  hint: {
    fontSize: 12,
    color: '#6B7280',
    marginTop: 2,
  },
  actions: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  retryButton: {
    padding: 4,
  },
  dismissButton: {
    padding: 4,
  },
});

export default ErrorToast;
