import * as ImagePicker from 'expo-image-picker';
import { useCallback, useEffect, useState } from 'react';
import { ActivityIndicator, Image, Pressable, ScrollView, StyleSheet, TextInput, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

import { Button } from '@/components/button';
import { Card } from '@/components/card';
import { ScreenBackground } from '@/components/screen-background';
import { ThemedText } from '@/components/themed-text';
import { Spacing, TopTabInset } from '@/constants/theme';
import { useTheme } from '@/hooks/use-theme';
import { useAuth } from '@/lib/auth-context';
import {
  createExercise,
  deleteExercise,
  getBadgesForAdmin,
  getFullCatalog,
  updateBadgePoints,
  updateExercise,
  uploadExercisePhoto,
  type AdminBadge,
  type CatalogExercise,
  type CatalogExerciseInput,
} from '@/lib/admin';
import { getProfile, updateMyProfile, type Profile } from '@/lib/profile';
import { errorMessage } from '@/lib/social';

const EMPTY_FORM: CatalogExerciseInput = {
  name: '',
  muscle_group: '',
  machine_name: '',
  default_target_sets: 4,
  default_target_reps: 12,
  image_url: null,
};

export default function AccountScreen() {
  const { session, signOut, updatePassword, updateEmail } = useAuth();
  const theme = useTheme();
  const userId = session!.user.id;

  const [profile, setProfile] = useState<Profile | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);

  const [nameDraft, setNameDraft] = useState('');
  const [emailDraft, setEmailDraft] = useState(session?.user.email ?? '');
  const [passwordDraft, setPasswordDraft] = useState('');
  const [savingName, setSavingName] = useState(false);
  const [savingEmail, setSavingEmail] = useState(false);
  const [savingPassword, setSavingPassword] = useState(false);

  const [catalog, setCatalog] = useState<CatalogExercise[]>([]);
  const [badges, setBadges] = useState<AdminBadge[]>([]);
  const [badgeDrafts, setBadgeDrafts] = useState<Record<string, string>>({});
  const [savingBadge, setSavingBadge] = useState<Record<string, boolean>>({});
  const [savedBadge, setSavedBadge] = useState<Record<string, boolean>>({});
  const [showForm, setShowForm] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [form, setForm] = useState<CatalogExerciseInput>(EMPTY_FORM);
  const [uploading, setUploading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [deletingId, setDeletingId] = useState<number | null>(null);

  const loadAdminData = useCallback(async () => {
    const [catalogData, badgesData] = await Promise.all([getFullCatalog(), getBadgesForAdmin()]);
    setCatalog(catalogData);
    setBadges(badgesData);
    setBadgeDrafts(Object.fromEntries(badgesData.map((b) => [b.code, String(b.points_reward)])));
  }, []);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const profileData = await getProfile(userId);
      setProfile(profileData);
      setNameDraft(profileData?.display_name ?? '');
      if (profileData?.is_admin) await loadAdminData();
    } catch (e) {
      setError(errorMessage(e));
    }
    setLoading(false);
  }, [userId, loadAdminData]);

  useEffect(() => {
    load();
  }, [load]);

  async function selectAvatarGender(value: 'masculino' | 'femenino') {
    if (!profile || profile.avatar_gender === value) return;
    setError(null);
    try {
      await updateMyProfile(userId, { avatar_gender: value });
      setProfile({ ...profile, avatar_gender: value });
    } catch (e) {
      setError(errorMessage(e));
    }
  }

  async function saveName() {
    setSavingName(true);
    setError(null);
    setInfo(null);
    try {
      await updateMyProfile(userId, { display_name: nameDraft.trim() });
      setInfo('Nombre actualizado.');
    } catch (e) {
      setError(errorMessage(e));
    }
    setSavingName(false);
  }

  async function saveEmail() {
    setSavingEmail(true);
    setError(null);
    setInfo(null);
    const result = await updateEmail(emailDraft.trim());
    setSavingEmail(false);
    if (result) return setError(result);
    setInfo('Revisa tu correo para confirmar el cambio de email.');
  }

  async function savePassword() {
    if (!passwordDraft) return;
    setSavingPassword(true);
    setError(null);
    setInfo(null);
    const result = await updatePassword(passwordDraft);
    setSavingPassword(false);
    if (result) return setError(result);
    setPasswordDraft('');
    setInfo('Contraseña actualizada.');
  }

  function startCreate() {
    setEditingId(null);
    setForm(EMPTY_FORM);
    setShowForm(true);
  }

  function startEdit(exercise: CatalogExercise) {
    setEditingId(exercise.id);
    setForm({
      name: exercise.name,
      muscle_group: exercise.muscle_group ?? '',
      machine_name: exercise.machine_name ?? '',
      default_target_sets: exercise.default_target_sets,
      default_target_reps: exercise.default_target_reps,
      image_url: exercise.image_url,
    });
    setShowForm(true);
  }

  async function takePhoto() {
    const permission = await ImagePicker.requestCameraPermissionsAsync();
    if (!permission.granted) return setError('Necesitamos permiso de cámara para tomar la foto.');

    const result = await ImagePicker.launchCameraAsync({ quality: 0.6, allowsEditing: true });
    if (result.canceled) return;

    setUploading(true);
    try {
      const url = await uploadExercisePhoto(result.assets[0].uri);
      setForm((prev) => ({ ...prev, image_url: url }));
    } catch (e) {
      setError(errorMessage(e));
    }
    setUploading(false);
  }

  async function pickFromLibrary() {
    const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (!permission.granted) return setError('Necesitamos permiso para acceder a tus fotos.');

    const result = await ImagePicker.launchImageLibraryAsync({ quality: 0.6, allowsEditing: true });
    if (result.canceled) return;

    setUploading(true);
    try {
      const url = await uploadExercisePhoto(result.assets[0].uri);
      setForm((prev) => ({ ...prev, image_url: url }));
    } catch (e) {
      setError(errorMessage(e));
    }
    setUploading(false);
  }

  async function saveExercise() {
    if (!form.name.trim()) return;
    setSaving(true);
    setError(null);
    setInfo(null);
    try {
      if (editingId) {
        await updateExercise(editingId, form);
        setInfo('Ejercicio actualizado.');
      } else {
        await createExercise(form);
        setInfo('Ejercicio creado.');
      }
      setShowForm(false);
      await loadAdminData();
    } catch (e) {
      setError(errorMessage(e));
    }
    setSaving(false);
  }

  async function removeExercise(id: number) {
    setError(null);
    setInfo(null);
    setDeletingId(id);
    try {
      await deleteExercise(id);
      setInfo('Ejercicio eliminado.');
      await loadAdminData();
    } catch (e) {
      setError(errorMessage(e));
    }
    setDeletingId(null);
  }

  async function saveBadgePoints(code: string) {
    const value = parseInt(badgeDrafts[code] ?? '0', 10);
    if (Number.isNaN(value)) return;
    setError(null);
    setSavedBadge((prev) => ({ ...prev, [code]: false }));
    setSavingBadge((prev) => ({ ...prev, [code]: true }));
    try {
      await updateBadgePoints(code, value);
      setBadges((prev) => prev.map((b) => (b.code === code ? { ...b, points_reward: value } : b)));
      setSavedBadge((prev) => ({ ...prev, [code]: true }));
      setTimeout(() => setSavedBadge((prev) => ({ ...prev, [code]: false })), 2000);
    } catch (e) {
      setError(errorMessage(e));
    }
    setSavingBadge((prev) => ({ ...prev, [code]: false }));
  }

  if (loading) {
    return (
      <ScreenBackground style={styles.centered}>
        <ActivityIndicator />
      </ScreenBackground>
    );
  }

  return (
    <ScreenBackground style={styles.container}>
      <SafeAreaView style={styles.safeArea}>
        <ScrollView contentContainerStyle={styles.scrollContent}>
          <ThemedText type="title" style={styles.title}>
            Perfil
          </ThemedText>

          {error && (
            <ThemedText type="small" themeColor="error">
              {error}
            </ThemedText>
          )}
          {info && (
            <ThemedText type="small" themeColor="success">
              {info}
            </ThemedText>
          )}

          <ThemedText type="smallBold">Nombre</ThemedText>
          <Card>
            <TextInput
              value={nameDraft}
              onChangeText={setNameDraft}
              style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
            />
            <Button
              variant="ghost"
              label="Guardar nombre"
              loading={savingName}
              onPress={saveName}
              style={styles.inlineButton}
            />
          </Card>

          <ThemedText type="smallBold">Avatar</ThemedText>
          <Card>
            <ThemedText type="small" themeColor="textSecondary">
              Elige qué personaje usar cuando agreguemos las ilustraciones reales.
            </ThemedText>
            <View style={styles.relationRow}>
              {(['masculino', 'femenino'] as const).map((g) => (
                <Pressable
                  key={g}
                  onPress={() => selectAvatarGender(g)}
                  style={[
                    styles.chip,
                    { borderColor: theme.tint },
                    profile?.avatar_gender === g && { backgroundColor: theme.tint },
                  ]}>
                  <ThemedText type="small" themeColor={profile?.avatar_gender === g ? 'background' : 'tint'}>
                    {g === 'masculino' ? 'Masculino' : 'Femenino'}
                  </ThemedText>
                </Pressable>
              ))}
            </View>
          </Card>

          <ThemedText type="smallBold">Email</ThemedText>
          <Card>
            <TextInput
              value={emailDraft}
              onChangeText={setEmailDraft}
              autoCapitalize="none"
              keyboardType="email-address"
              style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
            />
            <Button
              variant="ghost"
              label="Guardar email"
              loading={savingEmail}
              onPress={saveEmail}
              style={styles.inlineButton}
            />
          </Card>

          <ThemedText type="smallBold">Contraseña</ThemedText>
          <Card>
            <TextInput
              placeholder="Nueva contraseña"
              placeholderTextColor={theme.textSecondary}
              value={passwordDraft}
              onChangeText={setPasswordDraft}
              secureTextEntry
              style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
            />
            <Button
              variant="ghost"
              label="Guardar contraseña"
              loading={savingPassword}
              onPress={savePassword}
              style={styles.inlineButton}
            />
          </Card>

          <Pressable onPress={signOut}>
            <ThemedText type="link" themeColor="error">
              Cerrar sesión
            </ThemedText>
          </Pressable>

          {profile?.is_admin && (
            <>
              <View style={styles.headerRow}>
                <ThemedText type="smallBold">Catálogo de ejercicios</ThemedText>
                <Pressable onPress={showForm ? () => setShowForm(false) : startCreate}>
                  <ThemedText type="link" themeColor="tint">
                    {showForm ? 'Cancelar' : '+ Nuevo'}
                  </ThemedText>
                </Pressable>
              </View>

              {showForm && (
                <Card>
                  <TextInput
                    placeholder="Nombre del ejercicio"
                    placeholderTextColor={theme.textSecondary}
                    value={form.name}
                    onChangeText={(text) => setForm((prev) => ({ ...prev, name: text }))}
                    style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
                  />
                  <TextInput
                    placeholder="Grupo muscular (ej. pierna)"
                    placeholderTextColor={theme.textSecondary}
                    value={form.muscle_group}
                    onChangeText={(text) => setForm((prev) => ({ ...prev, muscle_group: text }))}
                    style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
                  />
                  <TextInput
                    placeholder="Nombre de la máquina"
                    placeholderTextColor={theme.textSecondary}
                    value={form.machine_name}
                    onChangeText={(text) => setForm((prev) => ({ ...prev, machine_name: text }))}
                    style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
                  />
                  <View style={styles.metaRow}>
                    <View style={styles.metaField}>
                      <ThemedText type="small" themeColor="textSecondary">
                        Series meta
                      </ThemedText>
                      <TextInput
                        keyboardType="number-pad"
                        value={String(form.default_target_sets)}
                        onChangeText={(text) =>
                          setForm((prev) => ({ ...prev, default_target_sets: parseInt(text, 10) || 0 }))
                        }
                        style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
                      />
                    </View>
                    <View style={styles.metaField}>
                      <ThemedText type="small" themeColor="textSecondary">
                        Reps meta
                      </ThemedText>
                      <TextInput
                        keyboardType="number-pad"
                        value={String(form.default_target_reps)}
                        onChangeText={(text) =>
                          setForm((prev) => ({ ...prev, default_target_reps: parseInt(text, 10) || 0 }))
                        }
                        style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
                      />
                    </View>
                  </View>

                  {form.image_url && <Image source={{ uri: form.image_url }} style={styles.preview} />}

                  <View style={styles.relationRow}>
                    <Button label="📷 Tomar foto" onPress={takePhoto} disabled={uploading} style={styles.smallButton} />
                    <Pressable onPress={pickFromLibrary} disabled={uploading}>
                      <ThemedText type="link" themeColor="tint">
                        Elegir de galería
                      </ThemedText>
                    </Pressable>
                  </View>
                  {uploading && <ActivityIndicator />}

                  <Button
                    label={editingId ? 'Guardar cambios' : 'Crear ejercicio'}
                    loading={saving}
                    onPress={saveExercise}
                    style={styles.button}
                  />
                </Card>
              )}

              {catalog.map((exercise) => (
                <Card key={exercise.id}>
                  <View style={styles.exerciseRow}>
                    {exercise.image_url && <Image source={{ uri: exercise.image_url }} style={styles.thumb} />}
                    <View style={{ flex: 1, gap: Spacing.half }}>
                      <ThemedText type="smallBold">{exercise.name}</ThemedText>
                      <ThemedText type="small" themeColor="textSecondary">
                        {exercise.muscle_group} · {exercise.machine_name} · Meta {exercise.default_target_sets}x
                        {exercise.default_target_reps}
                      </ThemedText>
                    </View>
                  </View>
                  <View style={styles.relationRow}>
                    <Pressable onPress={() => startEdit(exercise)}>
                      <ThemedText type="link" themeColor="tint">
                        Editar
                      </ThemedText>
                    </Pressable>
                    {deletingId === exercise.id ? (
                      <ActivityIndicator />
                    ) : (
                      <Pressable onPress={() => removeExercise(exercise.id)}>
                        <ThemedText type="link" themeColor="error">
                          Eliminar
                        </ThemedText>
                      </Pressable>
                    )}
                  </View>
                </Card>
              ))}

              <ThemedText type="smallBold">Puntaje de logros</ThemedText>
              {badges.map((badge) => (
                <Card key={badge.code}>
                  <ThemedText type="smallBold">{badge.name}</ThemedText>
                  <ThemedText type="small" themeColor="textSecondary">
                    {badge.description}
                  </ThemedText>
                  <View style={styles.relationRow}>
                    <TextInput
                      keyboardType="number-pad"
                      value={badgeDrafts[badge.code] ?? '0'}
                      onChangeText={(text) => {
                        setBadgeDrafts((prev) => ({ ...prev, [badge.code]: text }));
                        setSavedBadge((prev) => ({ ...prev, [badge.code]: false }));
                      }}
                      style={[styles.pointsInput, { color: theme.text, borderColor: theme.text + '30' }]}
                    />
                    {savingBadge[badge.code] ? (
                      <ActivityIndicator />
                    ) : savedBadge[badge.code] ? (
                      <ThemedText type="small" themeColor="success">
                        ✅ Guardado
                      </ThemedText>
                    ) : (
                      <Pressable onPress={() => saveBadgePoints(badge.code)}>
                        <ThemedText type="link" themeColor="tint">
                          Guardar
                        </ThemedText>
                      </Pressable>
                    )}
                  </View>
                </Card>
              ))}
            </>
          )}
        </ScrollView>
      </SafeAreaView>
    </ScreenBackground>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  centered: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  safeArea: { flex: 1 },
  scrollContent: {
    paddingHorizontal: Spacing.four,
    paddingTop: Spacing.four + TopTabInset,
    paddingBottom: Spacing.six,
    gap: Spacing.three,
  },
  title: { fontSize: 32, lineHeight: 40 },
  headerRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginTop: Spacing.three,
  },
  input: {
    borderWidth: 1,
    borderRadius: Spacing.two,
    paddingHorizontal: Spacing.three,
    paddingVertical: Spacing.two,
    fontSize: 16,
  },
  metaRow: { flexDirection: 'row', gap: Spacing.two },
  metaField: { flex: 1, gap: Spacing.half },
  relationRow: { flexDirection: 'row', flexWrap: 'wrap', gap: Spacing.three, alignItems: 'center' },
  chip: {
    borderWidth: 1,
    borderRadius: Spacing.five,
    paddingHorizontal: Spacing.three,
    paddingVertical: Spacing.one,
  },
  smallButton: {
    paddingHorizontal: Spacing.three,
    paddingVertical: Spacing.two,
  },
  button: { marginTop: Spacing.two },
  inlineButton: { alignSelf: 'flex-start', marginTop: Spacing.one },
  preview: {
    width: '100%',
    height: 160,
    borderRadius: Spacing.two,
  },
  thumb: {
    width: 56,
    height: 56,
    borderRadius: Spacing.two,
  },
  exerciseRow: {
    flexDirection: 'row',
    gap: Spacing.two,
    alignItems: 'center',
  },
  pointsInput: {
    borderWidth: 1,
    borderRadius: Spacing.two,
    paddingHorizontal: Spacing.two,
    paddingVertical: Spacing.one,
    fontSize: 14,
    width: 70,
  },
});
