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 { awardSessionPoints } from '@/lib/points';
import { supabase } from '@/lib/supabase';

type Exercise = {
  id: number;
  name: string;
  muscle_group: string | null;
  machine_name: string | null;
  image_url: string | null;
  default_target_sets: number;
  default_target_reps: number;
};

type RoutineExercise = {
  id: number;
  exercise_id: number;
  target_sets: number;
  target_reps: number;
  target_weight_kg: number | null;
  exercises: Exercise;
};

type Routine = { id: number; name: string };

type SessionSet = {
  id: number;
  exercise_id: number;
  set_number: number;
  weight_kg: number;
  reps: number;
};

export default function RutinaScreen() {
  const { session } = useAuth();
  const theme = useTheme();
  const userId = session!.user.id;

  const [loading, setLoading] = useState(true);
  const [routine, setRoutine] = useState<Routine | null>(null);
  const [routineExercises, setRoutineExercises] = useState<RoutineExercise[]>([]);
  const [catalog, setCatalog] = useState<Exercise[]>([]);
  const [showPicker, setShowPicker] = useState(false);
  const [activeSessionId, setActiveSessionId] = useState<number | null>(null);
  const [loggedSets, setLoggedSets] = useState<Record<number, SessionSet[]>>({});
  const [draftSets, setDraftSets] = useState<Record<number, { weight: string; reps: string }>>({});
  const [error, setError] = useState<string | null>(null);
  const [newRoutineName, setNewRoutineName] = useState('');

  const loadAll = useCallback(async () => {
    setLoading(true);
    setError(null);

    const { data: routines, error: routineError } = await supabase
      .from('routines')
      .select('id, name')
      .eq('user_id', userId)
      .eq('is_active', true)
      .order('created_at', { ascending: false })
      .limit(1);
    if (routineError) {
      setError(routineError.message);
      setLoading(false);
      return;
    }

    const activeRoutine = routines?.[0] ?? null;
    setRoutine(activeRoutine);

    if (activeRoutine) {
      const { data: exercisesData, error: exercisesError } = await supabase
        .from('routine_exercises')
        .select('id, exercise_id, target_sets, target_reps, target_weight_kg, exercises(*)')
        .eq('routine_id', activeRoutine.id)
        .order('position');
      if (exercisesError) {
        setError(exercisesError.message);
      } else {
        setRoutineExercises((exercisesData as any) ?? []);
      }

      const { data: openSession } = await supabase
        .from('workout_sessions')
        .select('id')
        .eq('user_id', userId)
        .eq('routine_id', activeRoutine.id)
        .is('ended_at', null)
        .order('started_at', { ascending: false })
        .limit(1);
      const session = openSession?.[0] ?? null;
      setActiveSessionId(session?.id ?? null);
      if (session) await loadSetsForSession(session.id);
    }

    const { data: catalogData } = await supabase
      .from('exercises')
      .select('*')
      .order('muscle_group')
      .order('name');
    setCatalog(catalogData ?? []);

    setLoading(false);
  }, [userId]);

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

  async function loadSetsForSession(sessionId: number) {
    const { data } = await supabase
      .from('session_sets')
      .select('*')
      .eq('session_id', sessionId)
      .order('set_number');
    const bySet: Record<number, SessionSet[]> = {};
    for (const set of data ?? []) {
      bySet[set.exercise_id] = [...(bySet[set.exercise_id] ?? []), set];
    }
    setLoggedSets(bySet);
  }

  async function createRoutine() {
    if (!newRoutineName.trim()) return;
    const { data, error } = await supabase
      .from('routines')
      .insert({ user_id: userId, name: newRoutineName.trim() })
      .select()
      .single();
    if (error) return setError(error.message);
    setRoutine(data);
    setNewRoutineName('');
  }

  async function addExercise(exercise: Exercise) {
    if (!routine) return;
    const { error } = await supabase.from('routine_exercises').insert({
      routine_id: routine.id,
      exercise_id: exercise.id,
      position: routineExercises.length,
      target_sets: exercise.default_target_sets,
      target_reps: exercise.default_target_reps,
    });
    if (error) return setError(error.message);
    await loadAll();
  }

  async function startSession() {
    if (!routine) return;
    const { data, error } = await supabase
      .from('workout_sessions')
      .insert({ user_id: userId, routine_id: routine.id })
      .select()
      .single();
    if (error) return setError(error.message);
    setActiveSessionId(data.id);
    setLoggedSets({});
  }

  async function finishSession() {
    if (!activeSessionId) return;
    const { error } = await supabase
      .from('workout_sessions')
      .update({ ended_at: new Date().toISOString() })
      .eq('id', activeSessionId);
    if (error) return setError(error.message);
    await awardSessionPoints(userId, activeSessionId);
    setActiveSessionId(null);
    setLoggedSets({});
    setDraftSets({});
  }

  async function addSet(exerciseId: number) {
    if (!activeSessionId) return;
    const draft = draftSets[exerciseId];
    const weight = parseFloat(draft?.weight ?? '');
    const reps = parseInt(draft?.reps ?? '', 10);
    if (Number.isNaN(weight) || Number.isNaN(reps)) return;

    const setNumber = (loggedSets[exerciseId]?.length ?? 0) + 1;
    const { data, error } = await supabase
      .from('session_sets')
      .insert({
        session_id: activeSessionId,
        exercise_id: exerciseId,
        set_number: setNumber,
        weight_kg: weight,
        reps,
      })
      .select()
      .single();
    if (error) return setError(error.message);

    setLoggedSets((prev) => ({ ...prev, [exerciseId]: [...(prev[exerciseId] ?? []), data] }));
    setDraftSets((prev) => ({ ...prev, [exerciseId]: { weight: '', reps: '' } }));
  }

  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}>
            {routine ? routine.name : 'Rutina'}
          </ThemedText>

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

          {!routine && (
            <Card>
              <ThemedText type="smallBold">Todavía no tienes una rutina</ThemedText>
              <TextInput
                placeholder="Nombre de la rutina (ej. Día de pierna)"
                placeholderTextColor={theme.textSecondary}
                value={newRoutineName}
                onChangeText={setNewRoutineName}
                style={[styles.input, { color: theme.text, borderColor: theme.text + '30' }]}
              />
              <Button label="Crear rutina" onPress={createRoutine} style={styles.button} />
            </Card>
          )}

          {routine && (
            <>
              {routineExercises.map((re) => (
                <Card key={re.id}>
                  <View style={styles.exerciseHeaderRow}>
                    {re.exercises.image_url && (
                      <Image source={{ uri: re.exercises.image_url }} style={styles.thumb} />
                    )}
                    <View style={{ flex: 1 }}>
                      <ThemedText type="smallBold">{re.exercises.name}</ThemedText>
                      <ThemedText type="small" themeColor="textSecondary">
                        Meta: {re.target_sets}x{re.target_reps}
                        {re.target_weight_kg ? ` @ ${re.target_weight_kg}kg` : ''}
                      </ThemedText>
                    </View>
                  </View>

                  {(loggedSets[re.exercise_id] ?? []).map((set) => (
                    <ThemedText key={set.id} type="small">
                      Serie {set.set_number}: {set.weight_kg}kg x {set.reps}
                    </ThemedText>
                  ))}

                  {activeSessionId && (
                    <View style={styles.setInputRow}>
                      <TextInput
                        placeholder="kg"
                        placeholderTextColor={theme.textSecondary}
                        keyboardType="decimal-pad"
                        value={draftSets[re.exercise_id]?.weight ?? ''}
                        onChangeText={(text) =>
                          setDraftSets((prev) => ({
                            ...prev,
                            [re.exercise_id]: { weight: text, reps: prev[re.exercise_id]?.reps ?? '' },
                          }))
                        }
                        style={[styles.smallInput, { color: theme.text, borderColor: theme.text + '30' }]}
                      />
                      <TextInput
                        placeholder="reps"
                        placeholderTextColor={theme.textSecondary}
                        keyboardType="number-pad"
                        value={draftSets[re.exercise_id]?.reps ?? ''}
                        onChangeText={(text) =>
                          setDraftSets((prev) => ({
                            ...prev,
                            [re.exercise_id]: { weight: prev[re.exercise_id]?.weight ?? '', reps: text },
                          }))
                        }
                        style={[styles.smallInput, { color: theme.text, borderColor: theme.text + '30' }]}
                      />
                      <Button label="+" onPress={() => addSet(re.exercise_id)} style={styles.addSetButton} />
                    </View>
                  )}
                </Card>
              ))}

              <Pressable onPress={() => setShowPicker((v) => !v)} style={styles.linkButton}>
                <ThemedText type="link" themeColor="tint">
                  {showPicker ? 'Cerrar catálogo' : '+ Agregar ejercicio'}
                </ThemedText>
              </Pressable>

              {showPicker && (
                <Card>
                  {catalog.map((exercise) => (
                    <Pressable
                      key={exercise.id}
                      onPress={() => addExercise(exercise)}
                      style={styles.catalogRow}>
                      {exercise.image_url && (
                        <Image source={{ uri: exercise.image_url }} style={styles.catalogThumb} />
                      )}
                      <View style={{ flex: 1 }}>
                        <ThemedText type="small">{exercise.name}</ThemedText>
                        <ThemedText type="small" themeColor="textSecondary">
                          {exercise.muscle_group}
                        </ThemedText>
                      </View>
                    </Pressable>
                  ))}
                </Card>
              )}

              {routineExercises.length > 0 && (
                <Button
                  label={activeSessionId ? 'Finalizar entreno' : 'Iniciar entreno'}
                  onPress={activeSessionId ? finishSession : startSession}
                  style={[styles.button, activeSessionId && { backgroundColor: theme.error }]}
                />
              )}
            </>
          )}
        </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 },
  input: {
    borderWidth: 1,
    borderRadius: Spacing.two,
    paddingHorizontal: Spacing.three,
    paddingVertical: Spacing.three,
    fontSize: 16,
  },
  smallInput: {
    borderWidth: 1,
    borderRadius: Spacing.two,
    paddingHorizontal: Spacing.two,
    paddingVertical: Spacing.two,
    fontSize: 14,
    width: 70,
  },
  setInputRow: {
    flexDirection: 'row',
    gap: Spacing.two,
    alignItems: 'center',
    marginTop: Spacing.one,
  },
  addSetButton: {
    borderRadius: Spacing.two,
    paddingHorizontal: Spacing.three,
    paddingVertical: Spacing.two,
  },
  button: {},
  linkButton: { alignItems: 'center', paddingVertical: Spacing.two },
  catalogRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: Spacing.two,
    paddingVertical: Spacing.two,
    borderBottomWidth: StyleSheet.hairlineWidth,
    borderBottomColor: '#80808030',
  },
  catalogThumb: {
    width: 40,
    height: 40,
    borderRadius: Spacing.one,
  },
  exerciseHeaderRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: Spacing.two,
  },
  thumb: {
    width: 56,
    height: 56,
    borderRadius: Spacing.two,
  },
});
