import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import * as ImagePicker from 'expo-image-picker';
import React, { useCallback, useEffect, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  Image,
  KeyboardAvoidingView,
  Modal,
  Platform,
  Pressable,
  StyleSheet,
  TextInput,
  TouchableOpacity,
  View,
  type ImageSourcePropType,
} from 'react-native';

import { ThemedText } from '@/components/themed-text';
import { deriveInitials } from '@/utils/profile-data';
import { uploadFile } from '@/lib/api/upload';
import { patchApiProfileName, patchApiProfileAvatar } from '@repo/loomart-sdk';
import { loomartClient } from '@/lib/api/loomart-client';
import { useAuth } from '@/hooks/use-auth';

type ProfileEditModalProps = {
  visible: boolean;
  avatarSource?: ImageSourcePropType;
  initialName: string;
  onClose: () => void;
  onSave: (payload: { name: string; avatar?: ImageSourcePropType }) => void;
};

export function ProfileEditModal({
  visible,
  avatarSource,
  initialName,
  onClose,
  onSave,
}: ProfileEditModalProps) {
  const palette = palettes.dark;
  const { refetch } = useAuth();
  const [nameValue, setNameValue] = useState(initialName);
  const [avatarCandidate, setAvatarCandidate] = useState<ImageSourcePropType | undefined>(avatarSource);
  const [isUploading, setIsUploading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);

  useEffect(() => {
    if (!visible) {
      return;
    }
    setNameValue(initialName);
    setAvatarCandidate(avatarSource);
  }, [visible, initialName, avatarSource]);

  const trimmedName = nameValue.trim();
  const initialTrimmedName = initialName.trim();
  const hasNameChanged = trimmedName !== initialTrimmedName;
  const avatarKey = getSourceKey(avatarCandidate);
  const initialAvatarKey = getSourceKey(avatarSource);
  const hasAvatarChanged = avatarKey !== initialAvatarKey;
  const isSaveDisabled = trimmedName.length === 0 || (!hasNameChanged && !hasAvatarChanged);

  const handlePickAvatar = useCallback(async () => {
    try {
      const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
      if (!permission.granted) {
        Alert.alert('需要权限', '请允许访问相册以选择头像');
        return;
      }

      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        allowsEditing: true,
        aspect: [1, 1],
        quality: 0.85,
      });

      if (result.canceled || !result.assets?.length) {
        return;
      }

      const asset = result.assets[0];
      if (!asset.uri) {
        return;
      }

      setIsUploading(true);
      const uploadResponse = await uploadFile(asset.uri, 'image');
      setIsUploading(false);

      if (uploadResponse.success && uploadResponse.data?.url) {
        setAvatarCandidate({ uri: uploadResponse.data.url });
      } else {
        Alert.alert('上传失败', uploadResponse.message || '图片上传失败，请稍后重试');
      }
    } catch (error) {
      setIsUploading(false);
      console.error('Failed to pick avatar', error);
      Alert.alert('选择失败', '无法打开相册，请稍后重试');
    }
  }, []);

  const handleSave = useCallback(async () => {
    if (trimmedName.length === 0) {
      return;
    }

    setIsSaving(true);

    try {
      if (hasNameChanged) {
        const nameResponse = await patchApiProfileName({
          client: loomartClient,
          body: { name: trimmedName },
        });

        if (!(nameResponse.data as any)?.success) {
          throw new Error('更新用户名失败');
        }
      }

      if (hasAvatarChanged && avatarCandidate && (avatarCandidate as any).uri) {
        const avatarResponse = await patchApiProfileAvatar({
          client: loomartClient,
          body: { image: (avatarCandidate as any).uri! },
        });

        if (!(avatarResponse.data as any)?.success) {
          throw new Error('更新头像失败');
        }
      }

      await refetch();

      onSave({
        name: trimmedName,
        avatar: avatarCandidate,
      });

      onClose();
    } catch (error) {
      console.error('保存失败:', error);
      Alert.alert('保存失败', error instanceof Error ? error.message : '保存用户信息失败，请稍后重试');
    } finally {
      setIsSaving(false);
    }
  }, [avatarCandidate, hasNameChanged, hasAvatarChanged, onClose, onSave, trimmedName, refetch]);

  return (
    <Modal
      transparent
      animationType="slide"
      visible={visible}
      onRequestClose={onClose}
    >
      <View style={styles.overlay}>
        <Pressable style={styles.backdrop} onPress={onClose} accessibilityRole="button" />
        <KeyboardAvoidingView
          behavior={Platform.OS === 'ios' ? 'padding' : undefined}
          style={styles.avoider}
        >
          <View style={[styles.card, { backgroundColor: palette.surface, borderColor: palette.frame }]}>
            <TouchableOpacity
              accessibilityRole="button"
              accessibilityLabel="Close profile editor"
              onPress={onClose}
              style={[styles.closeButton, { backgroundColor: palette.buttonGhost, borderColor: palette.frame }]}
              activeOpacity={0.85}
            >
              <MaterialIcons name="close" size={18} color={palette.muted} />
            </TouchableOpacity>

            <View style={styles.avatarSection}>
              <View
                style={[
                  styles.avatarShell,
                  { backgroundColor: palette.avatarBackdrop, borderColor: palette.frame },
                ]}
              >
                {avatarCandidate ? (
                  <Image source={avatarCandidate} style={styles.avatarImage} resizeMode="cover" />
                ) : (
                  <ThemedText style={[styles.avatarInitials, { color: palette.primary }]}>
                    {deriveInitials(trimmedName || initialName)}
                  </ThemedText>
                )}
              </View>
              <TouchableOpacity
                accessibilityRole="button"
                accessibilityLabel="Choose a new profile picture"
                onPress={handlePickAvatar}
                disabled={isUploading}
                style={[styles.cameraButton, { backgroundColor: palette.accent }]}
                activeOpacity={0.85}
              >
                {isUploading ? (
                  <ActivityIndicator size="small" color={palette.onAccent} />
                ) : (
                  <MaterialIcons name="photo-camera" size={18} color={palette.onAccent} />
                )}
              </TouchableOpacity>
            </View>

            <ThemedText style={[styles.modalTitle, { color: palette.primary }]}>
              Edit Profile
            </ThemedText>

            <View style={[styles.fieldWrapper, { backgroundColor: palette.field, borderColor: palette.frame }]}>
              <TextInput
                value={nameValue}
                onChangeText={setNameValue}
                placeholder="Display name"
                placeholderTextColor={palette.placeholder}
                style={[styles.textInput, { color: palette.primary }]}
                autoCapitalize="none"
                autoCorrect={false}
                returnKeyType="done"
                onSubmitEditing={handleSave}
              />
            </View>

            <TouchableOpacity
              accessibilityRole="button"
              accessibilityLabel="Save profile changes"
              onPress={handleSave}
              disabled={isSaveDisabled || isSaving}
              style={[
                styles.saveButton,
                {
                  backgroundColor: (isSaveDisabled || isSaving) ? palette.buttonGhost : palette.accent,
                  borderColor: (isSaveDisabled || isSaving) ? palette.frame : 'transparent',
                  borderWidth: (isSaveDisabled || isSaving) ? StyleSheet.hairlineWidth : 0,
                },
              ]}
              activeOpacity={0.9}
            >
              {isSaving ? (
                <ActivityIndicator size="small" color={palette.onAccent} />
              ) : (
                <ThemedText
                  style={[
                    styles.saveLabel,
                    { color: isSaveDisabled ? palette.muted : palette.onAccent },
                  ]}
                >
                  Save
                </ThemedText>
              )}
            </TouchableOpacity>
          </View>
        </KeyboardAvoidingView>
      </View>
    </Modal>
  );
}

const palettes = {
  dark: {
    surface: '#121216',
    frame: '#1D1E24',
    avatarBackdrop: '#1F2026',
    field: '#18181D',
    primary: '#F6F7FA',
    muted: '#8E9098',
    placeholder: '#5B5D66',
    accent: '#D1FE17',
    onAccent: '#050505',
    buttonGhost: '#101014',
  },
  light: {
    surface: '#FFFFFF',
    frame: '#D8DCE7',
    avatarBackdrop: '#E2E5EF',
    field: '#F3F5FC',
    primary: '#0F1320',
    muted: '#5E6474',
    placeholder: '#8C92A3',
    accent: '#405CFF',
    onAccent: '#FFFFFF',
    buttonGhost: '#EBEEF6',
  },
};

const styles = StyleSheet.create({
  overlay: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  backdrop: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: 'rgba(5,5,5,0.68)',
  },
  avoider: {
    width: '100%',
  },
  card: {
    borderTopLeftRadius: 28,
    borderTopRightRadius: 28,
    paddingHorizontal: 24,
    paddingTop: 32,
    paddingBottom: 28,
    borderWidth: 1,
    borderBottomWidth: 0,
    width: '100%',
  },
  closeButton: {
    alignSelf: 'flex-end',
    width: 34,
    height: 34,
    borderRadius: 17,
    borderWidth: 1,
    alignItems: 'center',
    justifyContent: 'center',
    marginBottom: 8,
  },
  avatarSection: {
    alignItems: 'center',
    marginBottom: 24,
  },
  avatarShell: {
    width: 88,
    height: 88,
    borderRadius: 44,
    overflow: 'hidden',
    borderWidth: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  avatarImage: {
    width: '100%',
    height: '100%',
  },
  avatarInitials: {
    fontSize: 28,
    fontWeight: '700',
  },
  cameraButton: {
    position: 'absolute',
    right: 18,
    bottom: 6,
    width: 36,
    height: 36,
    borderRadius: 18,
    alignItems: 'center',
    justifyContent: 'center',
  },
  modalTitle: {
    fontSize: 18,
    fontWeight: '700',
    textAlign: 'center',
    marginBottom: 20,
  },
  fieldWrapper: {
    borderRadius: 14,
    borderWidth: 1,
    marginBottom: 24,
    paddingHorizontal: 16,
    paddingVertical: 12,
  },
  textInput: {
    fontSize: 16,
    fontWeight: '600',
  },
  saveButton: {
    borderRadius: 999,
    paddingVertical: 14,
    alignItems: 'center',
    justifyContent: 'center',
  },
  saveLabel: {
    fontSize: 16,
    fontWeight: '700',
  },
});

function getSourceKey(source?: ImageSourcePropType): string | null {
  if (!source) {
    return null;
  }
  if (typeof source === 'number') {
    return String(source);
  }
  if (Array.isArray(source)) {
    return source.map(getSourceKey).join('|');
  }
  if ('uri' in source && source.uri) {
    return source.uri;
  }
  return null;
}
