import { useEffect, useRef, useState } from 'react';
import { Modal, View, Text, TouchableOpacity, Animated, Easing } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';

// ─── Message sanitization ─────────────────────────────────────────────────────

const HTML_TAG_RE = /<[^>]+>/g;
const STATUS_413_RE = /413|Request Entity Too Large|client_max_body_size/i;
const STATUS_4XX_RE = /API\s+4\d{2}|HTTP\s+4\d{2}/i;
const STATUS_5XX_RE = /API\s+5\d{2}|HTTP\s+5\d{2}|nginx|Internal Server Error/i;
const LOOKS_HTML_RE = /<!DOCTYPE|<html|<body|<head/i;
const LOOKS_JSON_RE = /^\s*[{[]/;

function sanitizeMessage(raw: string): { display: string; detail: string | null } {
  const stripped = raw.replace(HTML_TAG_RE, ' ').replace(/\s+/g, ' ').trim();

  if (STATUS_413_RE.test(raw)) {
    return { display: '', detail: stripped.length > 0 ? stripped.slice(0, 240) : null };
  }
  if (STATUS_4XX_RE.test(raw) || STATUS_5XX_RE.test(raw)) {
    return { display: '', detail: stripped.length > 0 ? stripped.slice(0, 240) : null };
  }
  if (LOOKS_HTML_RE.test(raw) || LOOKS_JSON_RE.test(raw) || stripped.length > 240) {
    return { display: '', detail: stripped.slice(0, 240) };
  }
  return { display: stripped, detail: null };
}

function friendlyMessage(raw: string, t: (k: string) => string): string {
  if (STATUS_413_RE.test(raw)) return t('alert.error_file_too_large');
  return t('alert.error_generic');
}

// ─── Types ────────────────────────────────────────────────────────────────────

export type AppAlertMode = 'error' | 'confirm' | 'success';

type BaseProps = {
  visible: boolean;
  title: string;
  message?: string;
};

type ErrorProps = BaseProps & {
  mode: 'error';
  onClose: () => void;
};

type SuccessProps = BaseProps & {
  mode: 'success';
  onClose: () => void;
};

type ConfirmProps = BaseProps & {
  mode: 'confirm';
  confirmLabel?: string;
  cancelLabel?: string;
  destructive?: boolean;
  onConfirm: () => void;
  onCancel: () => void;
};

export type AppAlertProps = ErrorProps | SuccessProps | ConfirmProps;

// ─── Component ───────────────────────────────────────────────────────────────

export function AppAlert(props: AppAlertProps) {
  const { t } = useTranslation();
  const { visible, title, message, mode } = props;

  const cardScale = useRef(new Animated.Value(0.85)).current;
  const cardOpacity = useRef(new Animated.Value(0)).current;
  const iconScale = useRef(new Animated.Value(0)).current;
  const iconRotate = useRef(new Animated.Value(0)).current;

  const [detailExpanded, setDetailExpanded] = useState(false);

  useEffect(() => {
    if (!visible) {
      setDetailExpanded(false);
      return;
    }
    cardScale.setValue(0.85);
    cardOpacity.setValue(0);
    iconScale.setValue(0);
    iconRotate.setValue(0);

    const animateIcon = mode === 'success';

    Animated.parallel([
      Animated.spring(cardScale, {
        toValue: 1,
        useNativeDriver: true,
        friction: 7,
        tension: 80,
      }),
      Animated.timing(cardOpacity, {
        toValue: 1,
        duration: 200,
        useNativeDriver: true,
        easing: Easing.out(Easing.cubic),
      }),
      animateIcon
        ? Animated.sequence([
            Animated.delay(130),
            Animated.parallel([
              Animated.spring(iconScale, {
                toValue: 1,
                useNativeDriver: true,
                friction: 5,
                tension: 180,
              }),
              Animated.timing(iconRotate, {
                toValue: 1,
                duration: 360,
                useNativeDriver: true,
                easing: Easing.out(Easing.back(1.7)),
              }),
            ]),
          ])
        : Animated.timing(iconScale, {
            toValue: 1,
            duration: 1,
            useNativeDriver: true,
          }),
    ]).start();
  }, [visible, mode, cardScale, cardOpacity, iconScale, iconRotate]);

  const rotateInterpolate = iconRotate.interpolate({
    inputRange: [0, 1],
    outputRange: ['-30deg', '0deg'],
  });

  // Sanitize message once
  const rawMessage = message ?? '';
  const { display: sanitizedDisplay, detail } = sanitizeMessage(rawMessage);
  const displayMessage = sanitizedDisplay.length > 0 ? sanitizedDisplay : friendlyMessage(rawMessage, t);

  const modeConfig = {
    error: {
      iconName: 'alert-circle' as const,
      iconBg: '#dc2626',
      okColor: '#dc2626',
      okBg: '#fef2f2',
      okBorder: '#fecaca',
    },
    success: {
      iconName: 'checkmark' as const,
      iconBg: '#16a34a',
      okColor: '#007AFF',
      okBg: '#eff6ff',
      okBorder: '#bfdbfe',
    },
    confirm: {
      iconName: 'help-circle' as const,
      iconBg: '#007AFF',
      okColor: '#007AFF',
      okBg: '#eff6ff',
      okBorder: '#bfdbfe',
    },
  }[mode];

  const onDismiss =
    mode === 'confirm'
      ? (props as ConfirmProps).onCancel
      : (props as ErrorProps | SuccessProps).onClose;

  const confirmLabel =
    mode === 'confirm'
      ? ((props as ConfirmProps).confirmLabel ?? t('common.confirm'))
      : t('common.ok');

  const cancelLabel =
    mode === 'confirm'
      ? ((props as ConfirmProps).cancelLabel ?? t('common.cancel'))
      : null;

  const destructive = mode === 'confirm' ? ((props as ConfirmProps).destructive ?? false) : false;

  const showMessage = mode === 'error'
    ? (rawMessage.length === 0 ? false : true)
    : !!message;

  const resolvedDisplayMessage = mode === 'error' ? displayMessage : (message ?? '');

  return (
    <Modal visible={visible} transparent animationType="fade" onRequestClose={onDismiss}>
      <TouchableOpacity
        activeOpacity={1}
        onPress={onDismiss}
        style={{
          flex: 1,
          backgroundColor: 'rgba(0,0,0,0.35)',
          justifyContent: 'center',
          alignItems: 'center',
          padding: 24,
        }}
      >
        <TouchableOpacity activeOpacity={1} onPress={() => {}} style={{ width: '88%', maxWidth: 340 }}>
          <Animated.View
            style={{
              backgroundColor: '#fff',
              borderRadius: 22,
              padding: 22,
              width: '100%',
              transform: [{ scale: cardScale }],
              opacity: cardOpacity,
              shadowColor: '#000',
              shadowOffset: { width: 0, height: 8 },
              shadowOpacity: 0.18,
              shadowRadius: 24,
              elevation: 16,
            }}
          >
            {/* Icon circle — animated for success, static otherwise */}
            <Animated.View
              style={{
                width: 56,
                height: 56,
                borderRadius: 28,
                backgroundColor: modeConfig.iconBg,
                alignItems: 'center',
                justifyContent: 'center',
                marginBottom: 14,
                alignSelf: 'center',
                transform:
                  mode === 'success'
                    ? [{ scale: iconScale }, { rotate: rotateInterpolate }]
                    : [{ scale: iconScale }],
                shadowColor: modeConfig.iconBg,
                shadowOffset: { width: 0, height: 4 },
                shadowOpacity: 0.35,
                shadowRadius: 8,
                elevation: 6,
              }}
            >
              <Ionicons name={modeConfig.iconName} size={32} color="#fff" />
            </Animated.View>

            {/* Title */}
            <Text
              style={{
                fontSize: 17,
                fontFamily: 'Nunito_700Bold',
                color: '#0a0a0a',
                textAlign: 'center',
                marginBottom: 8,
              }}
            >
              {title}
            </Text>

            {/* Message */}
            {showMessage && (
              <Text
                style={{
                  fontSize: 14,
                  fontFamily: 'Nunito_400Regular',
                  color: '#525252',
                  textAlign: 'center',
                  lineHeight: 20,
                  marginBottom: detail ? 6 : 18,
                }}
              >
                {resolvedDisplayMessage}
              </Text>
            )}

            {/* Expandable detail section for sanitized raw errors */}
            {detail && (
              <View style={{ marginBottom: 18 }}>
                <TouchableOpacity
                  activeOpacity={0.7}
                  onPress={() => setDetailExpanded((x) => !x)}
                  style={{
                    flexDirection: 'row',
                    alignItems: 'center',
                    justifyContent: 'center',
                    gap: 4,
                    paddingVertical: 4,
                  }}
                >
                  <Text
                    style={{
                      fontSize: 12,
                      fontFamily: 'Nunito_400Regular',
                      color: '#a3a3a3',
                    }}
                  >
                    {t('alert.details_label')}
                  </Text>
                  <Ionicons
                    name={detailExpanded ? 'chevron-up' : 'chevron-down'}
                    size={12}
                    color="#a3a3a3"
                  />
                </TouchableOpacity>
                {detailExpanded && (
                  <Text
                    style={{
                      fontSize: 11,
                      fontFamily: 'Nunito_400Regular',
                      color: '#a3a3a3',
                      textAlign: 'center',
                      lineHeight: 16,
                      marginTop: 4,
                      paddingHorizontal: 4,
                    }}
                  >
                    {detail}
                  </Text>
                )}
              </View>
            )}

            {/* Buttons */}
            {mode === 'confirm' ? (
              <View style={{ flexDirection: 'row', gap: 10 }}>
                <TouchableOpacity
                  activeOpacity={0.7}
                  onPress={(props as ConfirmProps).onCancel}
                  style={{
                    flex: 1,
                    paddingVertical: 10,
                    borderRadius: 10,
                    backgroundColor: '#f5f5f5',
                    alignItems: 'center',
                    justifyContent: 'center',
                  }}
                >
                  <Text
                    style={{
                      fontSize: 14,
                      fontFamily: 'Nunito_600SemiBold',
                      color: '#0a0a0a',
                    }}
                  >
                    {cancelLabel}
                  </Text>
                </TouchableOpacity>
                <TouchableOpacity
                  activeOpacity={0.7}
                  onPress={(props as ConfirmProps).onConfirm}
                  style={{
                    flex: 1,
                    paddingVertical: 10,
                    borderRadius: 10,
                    backgroundColor: destructive ? '#fef2f2' : '#eff6ff',
                    borderWidth: 1,
                    borderColor: destructive ? '#fecaca' : '#bfdbfe',
                    alignItems: 'center',
                    justifyContent: 'center',
                  }}
                >
                  <Text
                    style={{
                      fontSize: 14,
                      fontFamily: 'Nunito_700Bold',
                      color: destructive ? '#dc2626' : '#007AFF',
                    }}
                  >
                    {confirmLabel}
                  </Text>
                </TouchableOpacity>
              </View>
            ) : (
              <TouchableOpacity
                activeOpacity={0.7}
                onPress={onDismiss}
                style={{
                  paddingVertical: 10,
                  borderRadius: 10,
                  backgroundColor: modeConfig.okBg,
                  borderWidth: 1,
                  borderColor: modeConfig.okBorder,
                  alignItems: 'center',
                  justifyContent: 'center',
                }}
              >
                <Text
                  style={{
                    fontSize: 14,
                    fontFamily: 'Nunito_700Bold',
                    color: modeConfig.okColor,
                  }}
                >
                  {t('common.ok')}
                </Text>
              </TouchableOpacity>
            )}
          </Animated.View>
        </TouchableOpacity>
      </TouchableOpacity>
    </Modal>
  );
}
