import { useEffect, useMemo, useState } from 'react';
import Taro from '@tarojs/taro';
import { Button, Text, View } from '@tarojs/components';
import { loadVocabularyUnits, loadVocabularyWords, type VocabularyUnit } from '@/services/catalog';
import {
  loadFavoriteWords,
  loadVocabularyReviewPlan,
  loadVocabularyStats,
  reviewVocabularyWord,
  toggleWordFavorite,
  type VocabularyWord,
} from '@/services/learning';
import { playWordPronunciation, type AccentType } from '@/services/pronunciation';
import { getStorage, removeStorage, setStorage } from '@/services/storage';
import '../student.css';

type StudyMode = 'plan' | 'unit' | 'favorites';

type SessionStats = {
  known: number;
  unknown: number;
};

type ReviewPlanSummary = {
  dueCount: number;
  newCount: number;
  totalPlanned: number;
};

function wordKey(word: VocabularyWord) {
  return word.wordId || word.id || word.word;
}

function wordRecordId(word: VocabularyWord) {
  return word.wordId || word.id || '';
}

function progressStorageKey(unitId: string, mode: StudyMode) {
  return `tiku:vocabulary:${unitId || 'all'}:${mode}:index`;
}

function statNumber(stats: Record<string, unknown> | null, key: string) {
  const value = stats?.[key];
  return typeof value === 'number' ? value : Number(value || 0);
}

function percentText(value: number, total: number) {
  if (!total) return '0%';
  return `${Math.round((value / total) * 100)}%`;
}

function modeLabel(mode: StudyMode) {
  if (mode === 'favorites') return '收藏练习';
  if (mode === 'unit') return '单元学习';
  return '今日计划';
}

export default function StudentVocabularyPage() {
  const [units, setUnits] = useState<VocabularyUnit[]>([]);
  const [unitId, setUnitId] = useState('');
  const [mode, setMode] = useState<StudyMode>('plan');
  const [words, setWords] = useState<VocabularyWord[]>([]);
  const [favoriteIds, setFavoriteIds] = useState<Record<string, boolean>>({});
  const [stats, setStats] = useState<Record<string, unknown> | null>(null);
  const [planSummary, setPlanSummary] = useState<ReviewPlanSummary>({ dueCount: 0, newCount: 0, totalPlanned: 0 });
  const [index, setIndex] = useState(0);
  const [showAnswer, setShowAnswer] = useState(false);
  const [completed, setCompleted] = useState(false);
  const [accent, setAccent] = useState<AccentType>('us');
  const [sessionStats, setSessionStats] = useState<SessionStats>({ known: 0, unknown: 0 });
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  useEffect(() => {
    loadVocabularyUnits()
      .then(payload => {
        const nextUnits = payload.items || [];
        setUnits(nextUnits);
        if (nextUnits[0]) setUnitId(nextUnits[0].id);
      })
      .catch(nextError => setError(nextError instanceof Error ? nextError.message : '单词单元加载失败'));
  }, []);

  useEffect(() => {
    if (!unitId) return;
    setLoading(true);
    setError('');
    setCompleted(false);
    setShowAnswer(false);
    setSessionStats({ known: 0, unknown: 0 });

    Promise.all([
      mode === 'favorites' ? loadFavoriteWords(unitId) : Promise.resolve({ items: [] as VocabularyWord[] }),
      mode !== 'favorites' ? loadVocabularyWords(unitId) : Promise.resolve({ items: [] as VocabularyWord[] }),
      loadVocabularyReviewPlan(unitId).catch(() => ({ item: { words: [] as VocabularyWord[], dueCount: 0, newCount: 0, totalPlanned: 0 } })),
      loadFavoriteWords(unitId).catch(() => ({ items: [] as VocabularyWord[] })),
      loadVocabularyStats(unitId),
    ])
      .then(([favoritePayload, wordPayload, planPayload, favoritesForStatus, statPayload]) => {
        const planned = planPayload.item?.words || [];
        const nextWords = mode === 'favorites'
          ? favoritePayload.items || []
          : mode === 'unit'
            ? wordPayload.items || []
            : planned.length
              ? planned
              : wordPayload.items || [];
        setPlanSummary({
          dueCount: Number(planPayload.item?.dueCount || 0),
          newCount: Number(planPayload.item?.newCount || 0),
          totalPlanned: Number(planPayload.item?.totalPlanned || planned.length || 0),
        });
        const savedIndex = getStorage<number>(progressStorageKey(unitId, mode));
        setWords(nextWords);
        setFavoriteIds(Object.fromEntries((favoritesForStatus.items || []).map(item => wordRecordId(item)).filter(Boolean).map(id => [id, true])));
        setStats(statPayload.item || null);
        setIndex(typeof savedIndex === 'number' ? Math.min(savedIndex, Math.max(0, nextWords.length - 1)) : 0);
      })
      .catch(nextError => setError(nextError instanceof Error ? nextError.message : '单词加载失败'))
      .finally(() => setLoading(false));
  }, [unitId, mode]);

  useEffect(() => {
    if (!unitId || !words.length) return;
    setStorage(progressStorageKey(unitId, mode), index);
  }, [index, mode, unitId, words.length]);

  const current = words[index] || null;
  const progressPercent = words.length ? Math.round(((Math.min(index + 1, words.length)) / words.length) * 100) : 0;
  const favoriteCurrent = current ? !!favoriteIds[wordRecordId(current)] : false;
  const totalWords = statNumber(stats, 'totalWords');
  const progressedWords = statNumber(stats, 'progressedWords');
  const masteredWords = statNumber(stats, 'masteredWords');
  const learningWords = statNumber(stats, 'learningWords');
  const todayReviewed = statNumber(stats, 'todayReviewed');
  const favoriteWords = statNumber(stats, 'favoriteWords');
  const unstartedWords = Math.max(0, totalWords - progressedWords);
  const sessionTotal = sessionStats.known + sessionStats.unknown;
  const masteryBucket = Math.max(0, Math.min(10, Math.round((totalWords ? masteredWords / totalWords : 0) * 10)));

  const unitName = useMemo(() => units.find(item => item.id === unitId)?.name || '单词单元', [units, unitId]);

  function resetPosition(nextMode = mode) {
    removeStorage(progressStorageKey(unitId, nextMode));
    setIndex(0);
    setShowAnswer(false);
    setCompleted(false);
    setSessionStats({ known: 0, unknown: 0 });
  }

  function previousWord() {
    setIndex(prev => Math.max(0, prev - 1));
    setShowAnswer(false);
    setCompleted(false);
  }

  function nextWord() {
    if (index >= words.length - 1) {
      setCompleted(true);
      return;
    }
    setIndex(prev => Math.min(words.length - 1, prev + 1));
    setShowAnswer(false);
  }

  async function mark(result: 'known' | 'unknown') {
    if (!current) return;
    const id = wordRecordId(current);
    if (!id) {
      setError('单词数据缺少 ID，无法提交复习结果');
      return;
    }
    try {
      await reviewVocabularyWord(id, result);
      setSessionStats(prev => ({
        known: prev.known + (result === 'known' ? 1 : 0),
        unknown: prev.unknown + (result === 'unknown' ? 1 : 0),
      }));
      if (mode === 'plan') {
        const nextWords = words.filter(item => wordKey(item) !== id);
        setWords(nextWords);
        setCompleted(!nextWords.length);
        setIndex(prev => Math.min(prev, Math.max(0, nextWords.length - 1)));
        setShowAnswer(false);
      } else {
        nextWord();
      }
      void refreshStats();
    } catch (nextError) {
      setError(nextError instanceof Error ? nextError.message : '复习提交失败');
    }
  }

  async function toggleFavorite() {
    if (!current) return;
    const id = wordRecordId(current);
    if (!id) {
      setError('单词数据缺少 ID，无法收藏');
      return;
    }
    const nextFavorite = !favoriteCurrent;
    try {
      const payload = await toggleWordFavorite(id, nextFavorite);
      setFavoriteIds(prev => ({ ...prev, [id]: payload.favorite }));
      if (mode === 'favorites' && !payload.favorite) {
        setWords(prev => prev.filter(item => wordKey(item) !== id));
        setIndex(prev => Math.min(prev, Math.max(0, words.length - 2)));
      }
      void refreshStats();
      Taro.showToast({ title: payload.favorite ? '已收藏' : '已取消收藏', icon: 'success' });
    } catch (nextError) {
      setError(nextError instanceof Error ? nextError.message : '收藏操作失败');
    }
  }

  function jumpToWord(targetIndex: number) {
    setIndex(Math.max(0, Math.min(words.length - 1, targetIndex)));
    setShowAnswer(false);
    setCompleted(false);
  }

  async function refreshStats() {
    if (!unitId) return;
    try {
      const payload = await loadVocabularyStats(unitId);
      setStats(payload.item || null);
    } catch {
      // Keep the current snapshot; the next page reload or mode switch will reconcile stats.
    }
  }

  async function playCurrent() {
    if (!current?.word) return;
    await playWordPronunciation(current.word, accent);
  }

  return (
    <View className='student-page vocabulary-page'>
      <View className='student-topbar'>
        <View className='student-title-block'>
          <Text className='student-kicker'>Vocabulary</Text>
          <Text className='student-title'>背单词</Text>
          <Text className='student-subtitle'>{unitName} · {modeLabel(mode)} · 进度由后端复习计划维护</Text>
        </View>
      </View>

      <View className='toolbar'>
        {units.map(item => (
          <Button key={item.id} className={`pill-button ${item.id === unitId ? 'active' : ''}`} onClick={() => setUnitId(item.id)}>
            {item.name}
          </Button>
        ))}
      </View>

      <View className='toolbar wrap vocabulary-modebar'>
        <Button className={`pill-button ${mode === 'plan' ? 'active' : ''}`} onClick={() => setMode('plan')}>今日计划</Button>
        <Button className={`pill-button ${mode === 'unit' ? 'active' : ''}`} onClick={() => setMode('unit')}>单元学习</Button>
        <Button className={`pill-button ${mode === 'favorites' ? 'active' : ''}`} onClick={() => setMode('favorites')}>收藏练习</Button>
        <Button className='secondary-button' onClick={() => resetPosition()}>重新开始</Button>
      </View>

      <View className='section-block'>
        <Text className='section-heading'>学习概览</Text>
        <View className='report-panel vocabulary-overview-panel'>
          <View className='split-row'>
            <View>
              <Text className='row-main'>{unitName}</Text>
              <Text className='row-meta'>掌握率 {percentText(masteredWords, totalWords)} · 已开始 {percentText(progressedWords, totalWords)}</Text>
            </View>
            <Text className='status-badge'>{modeLabel(mode)}</Text>
          </View>
          <View className='progress-track vocabulary-mastery-track'>
            <View className={`progress-fill w-bucket-${masteryBucket}`} />
          </View>
          <View className='grid-two vocabulary-stats-grid'>
            <View className='metric compact-metric'><Text className='metric-value'>{String(totalWords)}</Text><Text className='metric-label'>总词数</Text></View>
            <View className='metric compact-metric'><Text className='metric-value'>{String(masteredWords)}</Text><Text className='metric-label'>已掌握</Text></View>
            <View className='metric compact-metric'><Text className='metric-value'>{String(learningWords)}</Text><Text className='metric-label'>学习中</Text></View>
            <View className='metric compact-metric'><Text className='metric-value'>{String(unstartedWords)}</Text><Text className='metric-label'>未开始</Text></View>
            <View className='metric compact-metric'><Text className='metric-value'>{String(todayReviewed)}</Text><Text className='metric-label'>今日复习</Text></View>
            <View className='metric compact-metric'><Text className='metric-value'>{String(favoriteWords)}</Text><Text className='metric-label'>已收藏</Text></View>
          </View>
          <Text className='row-meta vocabulary-plan-line'>
            今日计划 {String(planSummary.totalPlanned)} 个 · 待复习 {String(planSummary.dueCount)} 个 · 新词 {String(planSummary.newCount)} 个
          </Text>
        </View>
      </View>

      {loading ? <View className='empty-state section-block'>单词加载中...</View> : null}

      {!loading && current && !completed ? (
        <View className='vocabulary-study section-block'>
          <View className='vocabulary-progress'>
            <Text className='row-meta'>{index + 1}/{words.length} · {progressPercent}%</Text>
            <View className='vocabulary-progress-track'><View className='vocabulary-progress-fill' style={{ width: `${progressPercent}%` }} /></View>
          </View>

          <View className={`vocabulary-card ${showAnswer ? 'revealed' : ''}`} onClick={() => setShowAnswer(prev => !prev)}>
            <View className='amount-row'>
              <Text className='status-badge'>{current.dueLevel || current.status || modeLabel(mode)}</Text>
              <Text className='status-badge'>{favoriteCurrent ? '已收藏' : '未收藏'}</Text>
            </View>
            <Text className='vocabulary-word'>{current.word}</Text>
            {current.phonetic ? <Text className='vocabulary-phonetic'>/{current.phonetic}/</Text> : null}
            <View className='toolbar wrap vocabulary-card-actions'>
              <Button className='secondary-button' onClick={(event) => { event.stopPropagation(); void playCurrent(); }}>发音</Button>
              <Button className='secondary-button' onClick={(event) => { event.stopPropagation(); setAccent(prev => (prev === 'us' ? 'uk' : 'us')); }}>{accent === 'us' ? '美音' : '英音'}</Button>
              <Button className='secondary-button' onClick={(event) => { event.stopPropagation(); void toggleFavorite(); }}>{favoriteCurrent ? '取消收藏' : '收藏'}</Button>
            </View>
            <View className='vocabulary-answer'>
              {showAnswer ? (
                <>
                  <Text className='row-main'>{current.meaning || '暂无释义'}</Text>
                  {current.example ? <Text className='row-meta'>{current.example}</Text> : null}
                  {current.exampleTranslation ? <Text className='row-meta'>{current.exampleTranslation}</Text> : null}
                </>
              ) : (
                <Text className='row-meta'>点击卡片查看释义和例句</Text>
              )}
            </View>
          </View>

          <View className='toolbar wrap vocabulary-actions'>
            <Button className='secondary-button' onClick={previousWord}>上一个</Button>
            <Button className='danger-button' onClick={() => mark('unknown')}>再记</Button>
            <Button className='primary-button' onClick={() => mark('known')}>认识</Button>
            <Button className='secondary-button' onClick={nextWord}>下一个</Button>
          </View>

          <View className='grid-two section-block'>
            <View className='metric'><Text className='metric-value'>{String(sessionStats.known)}</Text><Text className='metric-label'>本次认识</Text></View>
            <View className='metric'><Text className='metric-value'>{String(sessionStats.unknown)}</Text><Text className='metric-label'>本次再记</Text></View>
            <View className='metric'><Text className='metric-value'>{String(sessionTotal)}</Text><Text className='metric-label'>本次复习</Text></View>
            <View className='metric'><Text className='metric-value'>{percentText(sessionStats.known, sessionTotal)}</Text><Text className='metric-label'>本次认识率</Text></View>
          </View>
        </View>
      ) : null}

      {!loading && (completed || !words.length) ? (
        <View className='report-panel section-block'>
          <Text className='metric-value'>{words.length ? '本组已完成' : '暂无单词'}</Text>
          <Text className='metric-label'>
            {mode === 'favorites' && !words.length ? '当前单元还没有收藏单词。' : '可以切换模式或重新开始本单元学习。'}
          </Text>
          <View className='toolbar wrap checkout-actions'>
            <Button className='primary-button' onClick={() => resetPosition()}>重新开始</Button>
            <Button className='secondary-button' onClick={() => setMode(mode === 'plan' ? 'unit' : 'plan')}>切换模式</Button>
          </View>
        </View>
      ) : null}

      {words.length ? (
        <View className='section-block'>
          <Text className='section-heading'>单词列表</Text>
          <View className='vocabulary-word-grid'>
            {words.map((item, itemIndex) => (
              <View
                className={`vocabulary-word-chip ${itemIndex === index ? 'active' : ''} ${favoriteIds[wordRecordId(item)] ? 'favorite' : ''}`}
                key={wordKey(item)}
                onClick={() => jumpToWord(itemIndex)}
              >
                <Text className='vocabulary-chip-word'>{item.word}</Text>
                <Text className='vocabulary-chip-meta'>{itemIndex + 1}</Text>
              </View>
            ))}
          </View>
        </View>
      ) : null}

      {error ? <Text className='error-text'>{error}</Text> : null}
    </View>
  );
}
