import { API_ENDPOINTS, buildApiUrl } from '@/assets/config/api';
import { useAuth } from '@/assets/contexts/useAuth';
import ChevronRightIcon from '@/assets/icons/chevron-right.svg';
import UserDeleteIcon from '@/assets/icons/user-xmark-solid-full.svg';
import LogoutIcon from '@/assets/icons/right-from-bracket-solid-full.svg';
import UserIcon from '@/assets/icons/user-solid-full.svg';
import { colors } from '@/assets/styles/colors';
import { UserInfoResponse } from '@/assets/types';
import styles from '@/styles/screens/tabs/perfil.styles';
import { type Href, router } from 'expo-router';
import { useEffect, useMemo, useState } from 'react';
import { LoadingSpinner } from '@/assets/components/LoadingSpinner';
import {
    Alert,
    Image,
    KeyboardAvoidingView,
    Modal,
    Platform,
    Pressable,
    RefreshControl,
    ScrollView,
    Text,
    TextInput,
    View,
} from 'react-native';
import Animated, {
  Easing,
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const ANIM_DURATION = 280;

const formatDisplayName = (nome?: string, apelido?: string) => {
  const parts = [nome?.trim(), apelido?.trim()].filter((p): p is string => !!p);
  return parts.length > 0 ? parts.join(' ') : null;
};

export default function Perfil() {
  const insets = useSafeAreaInsets();
  const { token, user: authUser, logout, updateProfile, isLoading } = useAuth();
  const [userInfo, setUserInfo] = useState<UserInfoResponse | null>(null);
  const [isLoadingProfile, setIsLoadingProfile] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [isEditingOpen, setIsEditingOpen] = useState(false);
  const [newPassword, setNewPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isDeletingAccount, setIsDeletingAccount] = useState(false);
  const [confirmModal, setConfirmModal] = useState<null | 'logout' | 'delete'>(null);

  const progress = useSharedValue(0);
  const contentHeight = useSharedValue(0);
  const [measuredHeight, setMeasuredHeight] = useState(0);

  useEffect(() => {
    if (measuredHeight > 0) {
      contentHeight.value = measuredHeight;
    }
  }, [measuredHeight, contentHeight]);

  useEffect(() => {
    progress.value = withTiming(isEditingOpen ? 1 : 0, {
      duration: ANIM_DURATION,
      easing: Easing.out(Easing.cubic),
    });
  }, [isEditingOpen, progress]);

  const editBodyAnimatedStyle = useAnimatedStyle(() => ({
    height: contentHeight.value * progress.value,
    opacity: progress.value,
  }));

  const chevronAnimatedStyle = useAnimatedStyle(() => ({
    transform: [{ rotate: `${progress.value * 90}deg` }],
  }));

  const getUserInfo = async () => {
    if (!token) {
      setUserInfo(null);
      setIsLoadingProfile(false);
      return;
    }
    setIsLoadingProfile(true);
    try {
      const formData = new FormData();
      formData.append('token', token);
      const response = await fetch(buildApiUrl(API_ENDPOINTS.USER_INFO), {
        method: 'POST',
        body: formData,
      });
      const data: UserInfoResponse = await response.json();
      setUserInfo(data);
    } catch {
      Alert.alert('Erro', 'Nao foi possivel carregar os dados do perfil.');
    } finally {
      setIsLoadingProfile(false);
    }
  };

  const displayName = useMemo(() => {
    const fromApi = formatDisplayName(userInfo?.user?.nome, userInfo?.user?.apelido);
    if (fromApi) return fromApi;
    return formatDisplayName(authUser?.nome, authUser?.apelido);
  }, [userInfo, authUser]);

  const displayEmail = userInfo?.user?.email?.trim() || authUser?.email?.trim() || null;

  useEffect(() => {
    getUserInfo();
  }, [token]);

  const onRefresh = async () => {
    setRefreshing(true);
    await getUserInfo();
    setRefreshing(false);
  };

  const handleSave = async () => {
    if (newPassword || confirmPassword) {
      if (!newPassword || !confirmPassword) {
        Alert.alert('Erro', 'Preenche os dois campos de palavra-passe.');
        return;
      }
      if (newPassword !== confirmPassword) {
        Alert.alert('Erro', 'As palavras-passe nao coincidem.');
        return;
      }
    }

    setIsSubmitting(true);
    try {
      await updateProfile(
        userInfo?.user?.nome,
        userInfo?.user?.apelido,
        undefined,
        newPassword || undefined,
      );
      Alert.alert('Sucesso', 'Perfil atualizado com sucesso.');
      setNewPassword('');
      setConfirmPassword('');
      setIsEditingOpen(false);
      await getUserInfo();
    } catch (err) {
      Alert.alert('Erro', err instanceof Error ? err.message : 'Nao foi possivel atualizar o perfil.');
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleLogout = () => {
    setConfirmModal('logout');
  };

  const handleDeleteAccount = () => {
    setConfirmModal('delete');
  };

  const confirmDeleteAccount = () => {
    Alert.alert(
      'Confirmacao final',
      'Todos os dados serao removidos permanentemente. Confirmar eliminacao?',
      [
        { text: 'Cancelar', style: 'cancel' },
        {
          text: 'Eliminar',
          style: 'destructive',
          onPress: async () => {
            if (!token) return;
            setIsDeletingAccount(true);
            try {
              const formData = new FormData();
              formData.append('token', token);
              const response = await fetch(buildApiUrl(API_ENDPOINTS.DELETE_ACCOUNT), {
                method: 'POST',
                body: formData,
              });
              const data = await response.json();
              if (response.ok && data?.status === 200) {
                await logout();
                router.replace('/login' as Href);
                Alert.alert('Conta eliminada', 'A sua conta foi eliminada com sucesso.');
              } else {
                Alert.alert('Erro', data?.message || 'Nao foi possivel eliminar a conta.');
              }
            } catch {
              Alert.alert('Erro', 'Falha ao contactar o servidor.');
            } finally {
              setIsDeletingAccount(false);
            }
          },
        },
      ]
    );
  };

  const confirmModalAction = async () => {
    if (confirmModal === 'logout') {
      try {
        await logout();
        setConfirmModal(null);
        router.replace('/login' as Href);
      } catch {
        Alert.alert('Erro', 'Nao foi possivel terminar sessao.');
      }
      return;
    }

    if (confirmModal === 'delete') {
      setConfirmModal(null);
      confirmDeleteAccount();
    }
  };

  const keyboardVerticalOffset = Platform.OS === 'ios' ? insets.top + 56 : 0;

  return (
    <KeyboardAvoidingView
      style={styles.container}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      keyboardVerticalOffset={keyboardVerticalOffset}>
      <ScrollView
        contentContainerStyle={styles.content}
        keyboardShouldPersistTaps="handled"
        keyboardDismissMode="on-drag"
        refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}>

        <Text style={styles.title}>O meu Perfil</Text>

        <View style={styles.userCard}>
          {isLoadingProfile && !displayName ? (
            <LoadingSpinner size="small" />
          ) : (
            <Text style={styles.userName}>{displayName || 'Utilizador'}</Text>
          )}
          <Text style={styles.userEmail}>{displayEmail || '—'}</Text>
        </View>

        <View style={styles.menuCard}>
          <Pressable style={styles.menuRow} onPress={() => setIsEditingOpen((prev) => !prev)}>
            <View style={styles.menuLeft}>
              <UserIcon width={24} height={24} fill={colors.azul} />
              <Text style={styles.menuText}>Editar Perfil</Text>
            </View>
            <Animated.View style={chevronAnimatedStyle}>
              <ChevronRightIcon width={18} height={18} fill={colors.vermelho} />
            </Animated.View>
          </Pressable>

          <Animated.View
            style={[styles.editBodyWrap, editBodyAnimatedStyle]}
            pointerEvents={isEditingOpen ? 'auto' : 'none'}>
            <View
              style={styles.editBodyMeasure}
              onLayout={(e) => {
                const h = Math.ceil(e.nativeEvent.layout.height);
                if (h > 0) setMeasuredHeight(h);
              }}>
              <View style={styles.accordionContent}>
                <View style={styles.rowInputs}>
                  <View style={styles.inputBlock}>
                    <Text style={styles.inputLabel}>Nome<Text style={styles.required}></Text></Text>
                    <TextInput
                      value={userInfo?.user?.nome || ''}
                      onChangeText={(text) =>
                        setUserInfo((prev) =>
                          prev?.user ? { ...prev, user: { ...prev.user, nome: text } } : prev,
                        )
                      }
                      style={styles.input}
                      placeholder="Nome"
                    />
                  </View>
                  <View style={styles.inputBlock}>
                    <Text style={styles.inputLabel}>Apelido<Text style={styles.required}></Text></Text>
                    <TextInput
                      value={userInfo?.user?.apelido || ''}
                      onChangeText={(text) =>
                        setUserInfo((prev) =>
                          prev?.user ? { ...prev, user: { ...prev.user, apelido: text } } : prev,
                        )
                      }
                      style={styles.input}
                      placeholder="Apelido"
                    />
                  </View>
                </View>

                <View style={styles.inputBlockFull}>
                  <Text style={styles.inputLabel}>Nova Palavra-passe<Text style={styles.required}></Text></Text>
                  <TextInput
                    value={newPassword}
                    onChangeText={setNewPassword}
                    style={styles.input}
                    placeholder="Palavra-passe"
                    secureTextEntry
                  />
                </View>

                <View style={styles.inputBlockFull}>
                  <Text style={styles.inputLabel}>Confirmar Nova Palavra-passe<Text style={styles.required}></Text></Text>
                  <TextInput
                    value={confirmPassword}
                    onChangeText={setConfirmPassword}
                    style={styles.input}
                    placeholder="Palavra-passe"
                    secureTextEntry
                  />
                </View>

                <Pressable style={styles.saveButton} onPress={handleSave} disabled={isSubmitting || isLoading}>
                  {isSubmitting ? (
                    <LoadingSpinner size="small" />
                  ) : (
                    <>
                      <Text style={styles.saveButtonText}>Guardar Alteracoes</Text>
                      <Image source={require('@/assets/icons/seta-up.png')} style={styles.saveButtonIcon} />
                    </>

                  )}
                </Pressable>
              </View>
            </View>
          </Animated.View>

          <View style={styles.divider} />

          <Pressable style={styles.menuRow} onPress={handleLogout}>
            <View style={styles.menuLeft}>
              <LogoutIcon width={24} height={24} fill={colors.azul} />
              <Text style={styles.menuText}>Log out</Text>
            </View>
            <ChevronRightIcon width={18} height={18} fill={colors.vermelho} />
          </Pressable>

          <View style={styles.divider} />

            <Pressable style={styles.menuRow} onPress={handleDeleteAccount} disabled={isDeletingAccount}>
              <View style={styles.menuLeft}>
                <UserDeleteIcon width={24} height={24} fill={colors.azul} />
                <Text style={styles.menuText}>{isDeletingAccount ? 'A eliminar...' : 'Eliminar Conta'}</Text>
              </View>
              <ChevronRightIcon width={18} height={18} fill={colors.vermelho} />
            </Pressable>
        </View>
      </ScrollView>

      {confirmModal && (
        <Modal visible transparent animationType="fade" onRequestClose={() => setConfirmModal(null)}>
          <View style={styles.modalOverlay}>
            <View style={styles.modalCard}>
              <View style={styles.modalIconWrap}>
                {confirmModal === 'delete' ? (
                  <UserDeleteIcon width={24} height={24} fill={colors.branco} />
                ) : (
                  <LogoutIcon width={24} height={24} fill={colors.branco} />
                )}
              </View>
              <Text style={styles.modalTitle}>
                {confirmModal === 'delete' ? 'Eliminar Conta' : 'Fazer Log out'}
              </Text>
              <Text style={styles.modalSubtitle}>
                {confirmModal === 'delete'
                  ? 'Tens a certeza que queres eliminar a tua conta?'
                  : 'Tens a certeza que queres sair da tua conta?'}
              </Text>

              <View style={styles.modalButtons}>
                <Pressable
                  style={[styles.modalButton, styles.modalPrimaryButton]}
                  onPress={confirmModalAction}
                  disabled={isDeletingAccount}>
                  <Text style={styles.modalPrimaryText}>
                    {confirmModal === 'delete' ? (isDeletingAccount ? 'A eliminar...' : 'Eliminar') : 'Sair'}
                  </Text>
                  <Image source={require('@/assets/icons/seta-up.png')} style={styles.saveButtonIcon} />
                </Pressable>

                <Pressable
                  style={[styles.modalButton, styles.modalSecondaryButton]}
                  onPress={() => setConfirmModal(null)}>
                  <Text style={styles.modalSecondaryText}>Cancelar</Text>
                  <Image source={require('@/assets/icons/seta-up-fill.png')} style={styles.arrowUpButtonIcon} />
                </Pressable>
              </View>
            </View>
          </View>
        </Modal>
      )}
    </KeyboardAvoidingView>
  );
}