import { Stack, useLocalSearchParams, useRouter } from 'expo-router';
import { useEffect, useMemo, useState } from 'react';
import { ActivityIndicator, Pressable, ScrollView, StyleSheet, 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, type Transcript } from '@/lib/db';
import { formatClock } from '@/lib/format';
import { generateQuiz, glossary, type QuizQuestion } from '@/lib/learn';

const ACCENT = '#3c87f7';
const CORRECT = '#30a46c';
const WRONG = '#e5484d';

export default function QuizScreen() {
  const theme = useTheme();
  const router = useRouter();
  const { id } = useLocalSearchParams<{ id: string }>();

  const [transcript, setTranscript] = useState<Transcript | null | undefined>(undefined);

  useEffect(() => {
    let alive = true;
    void getRepo()
      .get(id)
      .then((t) => {
        if (alive) setTranscript(t ?? null);
      });
    return () => {
      alive = false;
    };
  }, [id]);

  const questions = useMemo<QuizQuestion[]>(
    () => (transcript ? generateQuiz(glossary(transcript.segments)) : []),
    [transcript],
  );

  const [index, setIndex] = useState(0);
  const [picked, setPicked] = useState<number | null>(null);
  const [score, setScore] = useState(0);

  const total = questions.length;
  const q = index < total ? questions[index] : undefined;
  const finished = total > 0 && index >= total;

  const onPick = (optionIndex: number) => {
    if (picked !== null || !q) return;
    setPicked(optionIndex);
    if (optionIndex === q.answerIndex) setScore((s) => s + 1);
  };

  const next = () => {
    setPicked(null);
    setIndex((i) => i + 1);
  };

  const restart = () => {
    setIndex(0);
    setPicked(null);
    setScore(0);
  };

  if (transcript === undefined) {
    return (
      <Centered>
        <ActivityIndicator />
      </Centered>
    );
  }

  return (
    <ThemedView style={styles.fill}>
      <Stack.Screen options={{ title: 'Quiz' }} />
      <ScrollView contentContainerStyle={styles.content}>
        {transcript === null ? (
          <ThemedText type="small" themeColor="textSecondary" style={styles.pad}>
            Transcript not found.
          </ThemedText>
        ) : total === 0 ? (
          <ThemedText type="small" themeColor="textSecondary" style={styles.pad}>
            Not enough glossary terms to build a quiz for this lecture.
          </ThemedText>
        ) : finished ? (
          <ThemedView type="backgroundElement" style={styles.card}>
            <ThemedText type="subtitle">Quiz complete</ThemedText>
            <ThemedText type="default">
              You scored {score} of {total}.
            </ThemedText>
            <Pressable
              onPress={restart}
              style={({ pressed }) => [styles.primaryBtn, { backgroundColor: ACCENT, opacity: pressed ? 0.85 : 1 }]}>
              <ThemedText style={styles.primaryBtnText}>Try again</ThemedText>
            </Pressable>
            <Pressable
              onPress={() => router.push({ pathname: '/transcript/[id]', params: { id } })}
              style={({ pressed }) => [styles.secondaryBtn, { backgroundColor: theme.backgroundSelected, opacity: pressed ? 0.85 : 1 }]}>
              <ThemedText type="smallBold">Back to lecture</ThemedText>
            </Pressable>
          </ThemedView>
        ) : q ? (
          <>
            <ThemedText type="small" themeColor="textSecondary">
              Question {index + 1} of {total}
            </ThemedText>
            <ThemedText type="subtitle" style={styles.question}>{q.question}</ThemedText>

            <View style={styles.options}>
              {q.options.map((opt, i) => {
                const isAnswer = i === q.answerIndex;
                const isPicked = i === picked;
                const revealed = picked !== null;
                const border =
                  revealed && isAnswer ? CORRECT : revealed && isPicked ? WRONG : theme.backgroundElement;
                return (
                  <Pressable
                    key={i}
                    onPress={() => onPick(i)}
                    disabled={revealed}
                    style={({ pressed }) => [
                      styles.option,
                      { backgroundColor: theme.backgroundElement, borderColor: border, opacity: pressed && !revealed ? 0.8 : 1 },
                    ]}>
                    <ThemedText type="small">{opt}</ThemedText>
                  </Pressable>
                );
              })}
            </View>

            {picked !== null && (
              <ThemedView type="backgroundElement" style={styles.feedback}>
                <ThemedText type="smallBold" themeColor="textSecondary">
                  {picked === q.answerIndex ? 'Correct' : 'Incorrect'}
                </ThemedText>
                {q.start !== undefined && (
                  <Pressable
                    onPress={() =>
                      router.push({
                        pathname: '/transcript/[id]',
                        params: { id, t: String(Math.floor(q.start ?? 0)) },
                      })
                    }
                    hitSlop={6}>
                    <ThemedText type="linkPrimary">Jump to lecture ({formatClock(q.start)})</ThemedText>
                  </Pressable>
                )}
                <Pressable
                  onPress={next}
                  style={({ pressed }) => [styles.primaryBtn, { backgroundColor: ACCENT, opacity: pressed ? 0.85 : 1 }]}>
                  <ThemedText style={styles.primaryBtnText}>
                    {index + 1 >= total ? 'See score' : 'Next'}
                  </ThemedText>
                </Pressable>
              </ThemedView>
            )}
          </>
        ) : null}
      </ScrollView>
    </ThemedView>
  );
}

function Centered({ children }: { children: React.ReactNode }) {
  return <ThemedView style={[styles.fill, styles.centered]}>{children}</ThemedView>;
}

const styles = StyleSheet.create({
  fill: { flex: 1 },
  centered: { alignItems: 'center', justifyContent: 'center' },
  content: {
    padding: Spacing.three,
    gap: Spacing.three,
    maxWidth: MaxContentWidth,
    width: '100%',
    alignSelf: 'center',
  },
  card: { padding: Spacing.four, borderRadius: Spacing.three, gap: Spacing.three },
  question: { fontSize: 24, lineHeight: 32 },
  options: { gap: Spacing.two },
  option: { padding: Spacing.three, borderRadius: Spacing.three, borderWidth: 2 },
  feedback: { padding: Spacing.three, borderRadius: Spacing.three, gap: Spacing.two },
  primaryBtn: { paddingVertical: Spacing.three, borderRadius: Spacing.three, alignItems: 'center' },
  primaryBtnText: { color: '#fff', fontWeight: '700', fontSize: 16 },
  secondaryBtn: { paddingVertical: Spacing.three, borderRadius: Spacing.three, alignItems: 'center' },
  pad: { paddingVertical: Spacing.four, textAlign: 'center' },
});
