import React, { useEffect, useMemo, useState } from 'react';
import { Modal, Pressable, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import type { AlertButton } from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient';

import { bindDialogListener, DialogPayload } from '../../services/dialogService';
import { borderRadius, shadows, spacing, useAppColors, type AppColors } from '../../theme';

function createDialogHostStyles(colors: AppColors) {
  return StyleSheet.create({
    backdrop: {
      flex: 1,
      backgroundColor: 'rgba(0, 0, 0, 0.36)',
      justifyContent: 'center',
      alignItems: 'center',
      paddingHorizontal: spacing.xl,
    },
    container: {
      width: '100%',
      maxWidth: 380,
      backgroundColor: colors.background.paper,
      borderRadius: borderRadius['2xl'],
      paddingHorizontal: spacing.xl,
      paddingTop: spacing.lg,
      paddingBottom: spacing.lg,
      ...shadows.lg,
    },
    iconHeader: {
      alignItems: 'center',
      marginBottom: spacing.md,
    },
    iconBadge: {
      width: 42,
      height: 42,
      borderRadius: borderRadius.full,
      justifyContent: 'center',
      alignItems: 'center',
    },
    title: {
      color: colors.text.primary,
      fontSize: 18,
      fontWeight: '700',
      textAlign: 'center',
    },
    message: {
      marginTop: spacing.md,
      color: colors.text.secondary,
      fontSize: 14,
      lineHeight: 21,
      textAlign: 'center',
    },
    actions: {
      marginTop: spacing.xl,
      gap: spacing.sm,
    },
    actionButton: {
      height: 46,
      borderRadius: borderRadius.lg,
      borderWidth: 1,
      borderColor: `${colors.primary.main}28`,
      backgroundColor: colors.background.paper,
      justifyContent: 'center',
      alignItems: 'center',
    },
    primaryButton: {
      backgroundColor: colors.primary.main,
      borderColor: colors.primary.main,
    },
    cancelButton: {
      backgroundColor: colors.background.paper,
      borderColor: colors.divider,
    },
    destructiveButton: {
      backgroundColor: `${colors.error.main}18`,
      borderColor: `${colors.error.main}40`,
    },
    actionText: {
      color: colors.text.primary,
      fontSize: 15,
      fontWeight: '700',
    },
    primaryText: {
      color: colors.text.inverse,
    },
    cancelText: {
      color: colors.text.secondary,
      fontWeight: '600',
    },
    destructiveText: {
      color: colors.error.main,
    },
  });
}

const AppDialogHost: React.FC = () => {
  const [dialog, setDialog] = useState<DialogPayload | null>(null);
  const colors = useAppColors();
  const styles = useMemo(() => createDialogHostStyles(colors), [colors]);

  useEffect(() => {
    const unbind = bindDialogListener((payload) => {
      setDialog(payload);
    });
    return unbind;
  }, []);

  const actions = useMemo<AlertButton[]>(() => {
    if (!dialog?.actions?.length) return [{ text: '确定' }];
    return dialog.actions;
  }, [dialog]);

  const onClose = () => {
    const cancelAction = actions.find((action) => action.style === 'cancel');
    if (cancelAction?.onPress) {
      cancelAction.onPress();
    }
    setDialog(null);
  };

  const onActionPress = (action: AlertButton) => {
    action.onPress?.();
    setDialog(null);
  };

  return (
    <Modal
      visible={!!dialog}
      transparent
      animationType="fade"
      onRequestClose={onClose}
      statusBarTranslucent
    >
      <Pressable
        style={styles.backdrop}
        onPress={() => {
          if (dialog?.options?.cancelable ?? true) {
            onClose();
          }
        }}
      >
        <Pressable style={styles.container}>
          <View style={styles.iconHeader}>
            <LinearGradient
              colors={['#FF6B35', '#FF8F66']}
              start={{ x: 0, y: 0 }}
              end={{ x: 1, y: 1 }}
              style={styles.iconBadge}
            >
              <MaterialCommunityIcons name="carrot" size={20} color="#FFFFFF" />
            </LinearGradient>
          </View>
          <Text style={styles.title}>{dialog?.title || '提示'}</Text>
          {!!dialog?.message && <Text style={styles.message}>{dialog.message}</Text>}

          <View style={styles.actions}>
            {actions.map((action, index) => {
              const isDestructive = action.style === 'destructive';
              const isCancel = action.style === 'cancel';
              return (
                <TouchableOpacity
                  key={`${action.text || 'action'}-${index}`}
                  style={[
                    styles.actionButton,
                    isCancel && styles.cancelButton,
                    !isCancel && !isDestructive && styles.primaryButton,
                    isDestructive && styles.destructiveButton,
                  ]}
                  onPress={() => onActionPress(action)}
                  activeOpacity={0.8}
                >
                  <Text
                    style={[
                      styles.actionText,
                      !isCancel && !isDestructive && styles.primaryText,
                      isCancel && styles.cancelText,
                      isDestructive && styles.destructiveText,
                    ]}
                  >
                    {action.text || '确定'}
                  </Text>
                </TouchableOpacity>
              );
            })}
          </View>
        </Pressable>
      </Pressable>
    </Modal>
  );
};

export default AppDialogHost;
