import { useEffect, useCallback, useMemo } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import CircularProgress from '@mui/material/CircularProgress';
import CloseIcon from '@mui/icons-material/Close';
import { useLesson } from '../hooks/useLesson';
import { useSpeech } from '../hooks/useSpeech';
import { getLesson } from '../content/loader';
import { apiClient } from '../api/client';
import { ProgressBar } from '../components/layout/ProgressBar';
import { HeartsDisplay } from '../components/common/HeartsDisplay';
import { MultipleChoice } from '../components/exercises/MultipleChoice';
import { Translation, checkTranslation } from '../components/exercises/Translation';
import { MatchingPairs } from '../components/exercises/MatchingPairs';
import { FillInTheBlank } from '../components/exercises/FillInTheBlank';
import { SpeakExercise } from '../components/exercises/SpeakExercise';
import { CorrectBanner } from '../components/feedback/CorrectBanner';
import { IncorrectBanner } from '../components/feedback/IncorrectBanner';
import { SpeechBubble } from '../components/mascot/SpeechBubble';
import type { Exercise } from '../types/lesson';

function getCorrectAnswer(exercise: Exercise): string {
  switch (exercise.type) {
    case 'multiple-choice':
      return exercise.choices[exercise.correctIndex];
    case 'translation':
      return exercise.acceptedAnswers[0];
    case 'matching-pairs':
      return exercise.pairs.map((p) => `${p.left} = ${p.right}`).join(', ');
    case 'fill-in-the-blank':
      return exercise.blank;
    case 'speak':
      return exercise.acceptedAnswers[0];
  }
}

function isAnswerCorrect(exercise: Exercise, answer: unknown): boolean {
  switch (exercise.type) {
    case 'multiple-choice':
      return answer === exercise.correctIndex;

    case 'translation':
      return checkTranslation(
        (answer as string) || '',
        exercise.acceptedAnswers,
      );

    case 'matching-pairs': {
      const pairs = answer as Array<[string, string]> | null;
      return pairs != null && pairs.length === exercise.pairs.length;
    }

    case 'fill-in-the-blank': {
      const input = ((answer as string) || '').trim().toLowerCase();
      return input === exercise.blank.trim().toLowerCase();
    }

    case 'speak': {
      const spoken = ((answer as string) || '').trim().toLowerCase();
      return exercise.acceptedAnswers.some(
        (a) => a.trim().toLowerCase() === spoken,
      );
    }
  }
}

export function LessonPage() {
  const { topicId, lessonId } = useParams<{
    topicId: string;
    lessonId: string;
  }>();
  const navigate = useNavigate();
  const {
    state,
    setExercises,
    restoreState,
    selectAnswer,
    checkAnswer,
    nextExercise,
  } = useLesson();

  const { speak } = useSpeech();

  const lesson = useMemo(
    () => (topicId && lessonId ? getLesson(topicId, lessonId) : null),
    [topicId, lessonId],
  );

  // Load lesson exercises and restore saved state if available
  useEffect(() => {
    if (!lesson || !topicId || !lessonId) return;

    interface SavedState {
      current_index: number;
      hearts: number;
      correct_count: number;
    }

    apiClient
      .get<SavedState | null>(`/api/lesson-state/${topicId}/${lessonId}`)
      .then((saved) => {
        if (saved && saved.current_index > 0) {
          restoreState(
            lesson.exercises,
            saved.current_index,
            saved.hearts,
            saved.correct_count,
          );
        } else {
          setExercises(lesson.exercises);
        }
      })
      .catch(() => {
        // If fetching saved state fails, just start fresh
        setExercises(lesson.exercises);
      });
  }, [lesson, topicId, lessonId, setExercises, restoreState]);

  const currentExercise: Exercise | undefined =
    state.exercises[state.currentIndex];

  // Auto-play pronunciation when a new task is loaded
  useEffect(() => {
    if (!currentExercise || state.isChecked) return;

    let textToSpeak: string | null = null;

    if (currentExercise.type === 'speak') {
      textToSpeak = currentExercise.phrase;
    } else if (currentExercise.promptAudio) {
      textToSpeak = currentExercise.audioText ?? currentExercise.prompt;
    }

    if (textToSpeak) {
      speak(textToSpeak);
    }
    // Only trigger when the exercise index changes, not on every re-render
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [state.currentIndex, state.exercises]);

  const handleCheck = useCallback(() => {
    if (!currentExercise) return;
    const correct = isAnswerCorrect(currentExercise, state.selectedAnswer);
    checkAnswer(correct);
  }, [currentExercise, state.selectedAnswer, checkAnswer]);

  const handleContinue = useCallback(() => {
    if (!topicId || !lessonId) return;
    nextExercise();
    // Save progress after advancing to next exercise.
    // Use current state values which reflect the CHECK_ANSWER result.
    const nextIndex = state.currentIndex + 1;
    const isLast = nextIndex >= state.exercises.length;
    if (!isLast) {
      apiClient
        .put('/api/lesson-state', {
          topic_id: topicId,
          lesson_id: lessonId,
          current_index: nextIndex,
          hearts: state.hearts,
          correct_count: state.correctCount,
        })
        .catch(() => {
          // Save failed silently - not critical
        });
    }
  }, [nextExercise, topicId, lessonId, state.currentIndex, state.exercises.length, state.hearts, state.correctCount]);

  // Navigate to review when finished
  useEffect(() => {
    if (state.isFinished && lesson) {
      navigate('/review', {
        state: {
          correctCount: state.correctCount,
          total: state.exercises.length,
          xp: lesson.xpReward,
          topicId: lesson.topicId,
          lessonId: lesson.id,
          hearts: state.hearts,
        },
        replace: true,
      });
    }
  }, [state.isFinished, state.correctCount, state.exercises.length, state.hearts, lesson, navigate]);

  if (!lesson) {
    return (
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          flex: 1,
          py: 8,
        }}
      >
        <Typography color="text.secondary">Lesson not found</Typography>
        <Button
          variant="contained"
          onClick={() => navigate('/home')}
          sx={{ mt: 2 }}
        >
          Go Home
        </Button>
      </Box>
    );
  }

  if (state.exercises.length === 0) {
    return (
      <Box
        sx={{
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          flex: 1,
        }}
      >
        <CircularProgress color="primary" />
      </Box>
    );
  }

  if (!currentExercise) return null;

  const hasAnswer = state.selectedAnswer != null && state.selectedAnswer !== '';

  const showLowHearts = state.hearts > 0 && state.hearts <= 2 && !state.isChecked;
  const lowHeartMsg = state.hearts === 1 ? 'Kaya mo pa yan!' : 'Konting tiis pa!';

  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        flex: 1,
        maxWidth: 600,
        mx: 'auto',
        width: '100%',
        p: 2,
      }}
    >
      {/* Top bar: close, progress, hearts */}
      <Box
        sx={{
          display: 'flex',
          alignItems: 'center',
          gap: 2,
          mb: 4,
        }}
      >
        <IconButton
          onClick={() => navigate('/home')}
          sx={{ color: 'text.secondary' }}
        >
          <CloseIcon />
        </IconButton>
        <Box sx={{ flex: 1 }}>
          <ProgressBar
            current={state.currentIndex}
            total={state.exercises.length}
          />
        </Box>
        <HeartsDisplay hearts={state.hearts} />
      </Box>

      {/* Rambi encouragement when hearts are low */}
      {showLowHearts && (
        <Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}>
          <SpeechBubble
            mood={state.hearts === 1 ? 'sad' : 'encourage'}
            size={48}
            message={lowHeartMsg}
          />
        </Box>
      )}

      {/* Exercise area */}
      <Box
        sx={{
          flex: 1,
          display: 'flex',
          flexDirection: 'column',
          justifyContent: 'center',
          pb: state.isChecked ? 12 : 0,
        }}
      >
        {currentExercise.type === 'multiple-choice' && (
          <MultipleChoice
            exercise={currentExercise}
            selectedAnswer={
              typeof state.selectedAnswer === 'number'
                ? state.selectedAnswer
                : null
            }
            isChecked={state.isChecked}
            isCorrect={state.isCorrect}
            onSelect={(index) => selectAnswer(index)}
          />
        )}

        {currentExercise.type === 'translation' && (
          <Translation
            exercise={currentExercise}
            selectedAnswer={
              typeof state.selectedAnswer === 'string'
                ? state.selectedAnswer
                : null
            }
            isChecked={state.isChecked}
            onSelect={(text) => selectAnswer(text)}
          />
        )}

        {currentExercise.type === 'matching-pairs' && (
          <MatchingPairs
            exercise={currentExercise}
            selectedAnswer={
              Array.isArray(state.selectedAnswer)
                ? (state.selectedAnswer as Array<[string, string]>)
                : null
            }
            isChecked={state.isChecked}
            onSelect={(pairs) => selectAnswer(pairs)}
          />
        )}

        {currentExercise.type === 'fill-in-the-blank' && (
          <FillInTheBlank
            exercise={currentExercise}
            selectedAnswer={
              typeof state.selectedAnswer === 'string'
                ? state.selectedAnswer
                : null
            }
            isChecked={state.isChecked}
            onSelect={(text) => selectAnswer(text)}
          />
        )}

        {currentExercise.type === 'speak' && (
          <SpeakExercise
            exercise={currentExercise}
            selectedAnswer={
              typeof state.selectedAnswer === 'string'
                ? state.selectedAnswer
                : null
            }
            isChecked={state.isChecked}
            onSelect={(text) => selectAnswer(text)}
          />
        )}
      </Box>

      {/* Bottom: Check button (Continue is now inside feedback banners) */}
      {!state.isChecked && (
        <Box sx={{ py: 2 }}>
          <Button
            fullWidth
            variant="contained"
            color="primary"
            disabled={!hasAnswer}
            onClick={handleCheck}
            sx={{ py: 1.5 }}
          >
            Check
          </Button>
        </Box>
      )}

      {/* Feedback banners with embedded Continue button */}
      {state.isChecked && state.isCorrect === true && (
        <CorrectBanner onContinue={handleContinue} />
      )}
      {state.isChecked && state.isCorrect === false && (
        <IncorrectBanner
          correctAnswer={getCorrectAnswer(currentExercise)}
          onContinue={handleContinue}
        />
      )}
    </Box>
  );
}
