import { Link, Stack, useFocusEffect } from 'expo-router';
import { useCallback, useState } from 'react';
import { Pressable, ScrollView, StyleSheet, TextInput, View } from 'react-native';

import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { MaxContentWidth, Spacing } from '@/constants/theme';
import { useTheme } from '@/hooks/use-theme';
import { getRepo } from '@/lib/db';
import { useCourses } from '@/stores/coursesStore';

/** Per-course rollup shown on each row. */
interface CourseStat {
  count: number;
  hours: number;
}

export default function CoursesScreen() {
  const theme = useTheme();
  const { items, refresh, createCourse, rename, remove } = useCourses();
  const [name, setName] = useState('');
  const [editing, setEditing] = useState<string | null>(null);
  const [editName, setEditName] = useState('');
  const [stats, setStats] = useState<Record<string, CourseStat>>({});

  // Load the courses list, then roll up lecture count + total hours per course
  // in a single pass (one listByCourse() per course; fetched once on focus).
  const reload = useCallback(async () => {
    await refresh();
    const courses = useCourses.getState().items;
    const entries = await Promise.all(
      courses.map(async (c) => {
        const metas = await getRepo().listByCourse(c.id);
        const hours = metas.reduce((sum, m) => sum + m.durationSec, 0) / 3600;
        return [c.id, { count: metas.length, hours }] as const;
      }),
    );
    setStats(Object.fromEntries(entries));
  }, [refresh]);

  useFocusEffect(
    useCallback(() => {
      void reload();
    }, [reload]),
  );

  const add = async () => {
    const n = name.trim();
    if (!n) return;
    await createCourse({ name: n });
    setName('');
    await reload();
  };

  return (
    <ThemedView style={styles.fill}>
      <Stack.Screen options={{ title: 'Courses' }} />
      <ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled">
        <ThemedText type="small" themeColor="textSecondary">
          Group lectures by course. Deleting a course moves its transcripts to Unsorted (nothing is lost).
        </ThemedText>

        <View style={styles.row}>
          <TextInput
            value={name}
            onChangeText={setName}
            placeholder="New course name"
            placeholderTextColor={theme.textSecondary}
            style={[styles.input, styles.flex, { color: theme.text, backgroundColor: theme.backgroundElement }]}
          />
          <Pressable onPress={() => void add()} style={[styles.addBtn, { opacity: name.trim() ? 1 : 0.5 }]}>
            <ThemedText style={styles.white}>Add</ThemedText>
          </Pressable>
        </View>

        {items.length === 0 && (
          <ThemedText type="small" themeColor="textSecondary" style={styles.pad}>No courses yet.</ThemedText>
        )}

        {items.map((c) => (
          <ThemedView key={c.id} type="backgroundElement" style={styles.card}>
            {editing === c.id ? (
              <View style={styles.row}>
                <TextInput
                  value={editName}
                  onChangeText={setEditName}
                  autoFocus
                  style={[styles.input, styles.flex, { color: theme.text, backgroundColor: theme.background }]}
                />
                <Pressable
                  onPress={async () => {
                    if (editName.trim()) await rename(c.id, editName.trim());
                    setEditing(null);
                  }}
                  style={styles.addBtn}>
                  <ThemedText style={styles.white}>Save</ThemedText>
                </Pressable>
              </View>
            ) : (
              <View style={styles.rowBetween}>
                <View style={styles.flex}>
                  <ThemedText type="smallBold" numberOfLines={1}>{c.name}</ThemedText>
                  <ThemedText type="small" themeColor="textSecondary">
                    {statLine(stats[c.id])}
                  </ThemedText>
                </View>
                <View style={styles.actions}>
                  <Link href={{ pathname: '/bibliography', params: { courseId: c.id } }} asChild>
                    <Pressable hitSlop={8}>
                      <ThemedText type="small" themeColor="textSecondary">Bibliography</ThemedText>
                    </Pressable>
                  </Link>
                  <Pressable
                    onPress={() => {
                      setEditing(c.id);
                      setEditName(c.name);
                    }}
                    hitSlop={8}>
                    <ThemedText type="small" themeColor="textSecondary">Rename</ThemedText>
                  </Pressable>
                  <Pressable
                    onPress={async () => {
                      await remove(c.id);
                      await reload();
                    }}
                    hitSlop={8}>
                    <ThemedText type="small" themeColor="textSecondary">Delete</ThemedText>
                  </Pressable>
                </View>
              </View>
            )}
          </ThemedView>
        ))}
      </ScrollView>
    </ThemedView>
  );
}

/** "3 lectures · 4.2 h" — falls back to a zero state while stats load. */
function statLine(stat: CourseStat | undefined): string {
  const count = stat?.count ?? 0;
  const hours = stat?.hours ?? 0;
  const lectures = `${count} ${count === 1 ? 'lecture' : 'lectures'}`;
  return `${lectures} · ${hours.toFixed(1)} h`;
}

const styles = StyleSheet.create({
  fill: { flex: 1 },
  content: { padding: Spacing.three, gap: Spacing.two, maxWidth: MaxContentWidth, width: '100%', alignSelf: 'center' },
  row: { flexDirection: 'row', gap: Spacing.two, alignItems: 'center' },
  rowBetween: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: Spacing.two },
  flex: { flex: 1 },
  input: { borderRadius: Spacing.two, paddingHorizontal: Spacing.three, paddingVertical: Spacing.two, fontSize: 15 },
  addBtn: { backgroundColor: '#3c87f7', paddingHorizontal: Spacing.three, paddingVertical: Spacing.two, borderRadius: Spacing.two },
  white: { color: '#fff', fontWeight: '700' },
  card: { padding: Spacing.three, borderRadius: Spacing.three },
  actions: { flexDirection: 'row', gap: Spacing.three },
  pad: { paddingVertical: Spacing.four, textAlign: 'center' },
});
