import { useEffect, useMemo, useState } from 'react';
import Taro from '@tarojs/taro';
import { Button, Input, Text, View } from '@tarojs/components';
import RichContent, { safeTextContent } from '@/components/RichContent';
import { loadHandbookChapters, loadHandbookEntries, loadHandbookSubjects, type HandbookChapter, type HandbookEntry, type HandbookSubject } from '@/services/catalog';
import '../student.css';

interface HighlightPart {
  text: string;
  hit: boolean;
}

const SNIPPET_RADIUS = 42;

function normalizeQuery(value: string) {
  return value.trim().replace(/\s+/g, ' ').slice(0, 80);
}

function entrySearchText(entry: HandbookEntry) {
  return [entry.title, safeTextContent(entry.summary), safeTextContent(entry.content)]
    .filter(Boolean)
    .join('\n');
}

function entryMatches(entry: HandbookEntry, query: string) {
  if (!query) return true;
  return entrySearchText(entry).toLocaleLowerCase().includes(query.toLocaleLowerCase());
}

function firstSnippet(entry: HandbookEntry, query: string) {
  const text = entrySearchText(entry).replace(/\s+/g, ' ').trim();
  if (!text) return '';
  if (!query) return text.slice(0, 110);
  const lowerText = text.toLocaleLowerCase();
  const lowerQuery = query.toLocaleLowerCase();
  const index = lowerText.indexOf(lowerQuery);
  if (index < 0) return text.slice(0, 110);
  const start = Math.max(0, index - SNIPPET_RADIUS);
  const end = Math.min(text.length, index + query.length + SNIPPET_RADIUS);
  return `${start > 0 ? '...' : ''}${text.slice(start, end)}${end < text.length ? '...' : ''}`;
}

function highlightParts(text: string, query: string): HighlightPart[] {
  if (!text) return [];
  if (!query) return [{ text, hit: false }];
  const lowerText = text.toLocaleLowerCase();
  const lowerQuery = query.toLocaleLowerCase();
  const index = lowerText.indexOf(lowerQuery);
  if (index < 0) return [{ text, hit: false }];
  return [
    { text: text.slice(0, index), hit: false },
    { text: text.slice(index, index + query.length), hit: true },
    { text: text.slice(index + query.length), hit: false },
  ].filter(part => part.text.length > 0);
}

function safeEntryDomId(entryId: string) {
  return /^[a-zA-Z0-9_-]+$/.test(entryId) ? `handbook-entry-${entryId}` : '';
}

export default function StudentHandbookPage() {
  const [subjects, setSubjects] = useState<HandbookSubject[]>([]);
  const [chapters, setChapters] = useState<HandbookChapter[]>([]);
  const [entries, setEntries] = useState<HandbookEntry[]>([]);
  const [subjectId, setSubjectId] = useState('');
  const [chapterId, setChapterId] = useState('');
  const [searchQuery, setSearchQuery] = useState('');
  const [activeEntryId, setActiveEntryId] = useState('');
  const [error, setError] = useState('');

  const query = useMemo(() => normalizeQuery(searchQuery), [searchQuery]);
  const filteredEntries = useMemo(() => entries.filter(item => entryMatches(item, query)), [entries, query]);
  const activeEntry = useMemo(
    () => filteredEntries.find(item => item.id === activeEntryId) || filteredEntries[0] || null,
    [activeEntryId, filteredEntries],
  );

  useEffect(() => {
    loadHandbookSubjects()
      .then(payload => {
        const nextSubjects = payload.items || [];
        setSubjects(nextSubjects);
        if (nextSubjects[0]) setSubjectId(nextSubjects[0].id);
      })
      .catch(nextError => setError(nextError instanceof Error ? nextError.message : '知识手册加载失败'));
  }, []);

  useEffect(() => {
    if (!subjectId) return;
    setEntries([]);
    setSearchQuery('');
    setActiveEntryId('');
    loadHandbookChapters(subjectId)
      .then(payload => {
        const nextChapters = payload.items || [];
        setChapters(nextChapters);
        setChapterId(nextChapters[0]?.id || '');
      })
      .catch(nextError => setError(nextError instanceof Error ? nextError.message : '章节加载失败'));
  }, [subjectId]);

  useEffect(() => {
    if (!chapterId) return;
    setSearchQuery('');
    setActiveEntryId('');
    loadHandbookEntries(chapterId, true)
      .then(payload => {
        const nextEntries = payload.items || [];
        setEntries(nextEntries);
        setActiveEntryId(nextEntries[0]?.id || '');
      })
      .catch(nextError => setError(nextError instanceof Error ? nextError.message : '知识点加载失败'));
  }, [chapterId]);

  useEffect(() => {
    if (!filteredEntries.length) {
      setActiveEntryId('');
      return;
    }
    if (!activeEntryId || !filteredEntries.some(item => item.id === activeEntryId)) {
      setActiveEntryId(filteredEntries[0].id);
    }
  }, [activeEntryId, filteredEntries]);

  function selectEntry(entryId: string) {
    setActiveEntryId(entryId);
    const domId = safeEntryDomId(entryId);
    if (domId) {
      Taro.pageScrollTo({
        selector: `#${domId}`,
        duration: 220,
        offsetTop: 16,
      }).catch(() => undefined);
    }
  }

  return (
    <View className='student-page'>
      <View className='student-topbar'>
        <View className='student-title-block'>
          <Text className='student-kicker'>Handbook</Text>
          <Text className='student-title'>知识手册</Text>
          <Text className='student-subtitle'>内容由后端导入管线规范化，前端只负责阅读和筛选。</Text>
        </View>
      </View>

      <View className='section-block'>
        <Text className='section-heading'>手册科目</Text>
        <View className='list-stack'>
          {subjects.map(item => (
            <View className={`list-row ${item.id === subjectId ? 'active' : ''}`} key={item.id} onClick={() => setSubjectId(item.id)}>
              <Text className='row-main'>{item.name}</Text>
              <Text className='row-meta'>{item.description || item.type || '知识手册'}</Text>
            </View>
          ))}
        </View>
      </View>

      <View className='section-block'>
        <Text className='section-heading'>章节</Text>
        <View className='toolbar'>
          {chapters.map(item => (
            <View className={`pill-button ${item.id === chapterId ? 'active' : ''}`} key={item.id} onClick={() => setChapterId(item.id)}>
              <Text>{item.name}</Text>
            </View>
          ))}
        </View>
      </View>

      <View className='section-block'>
        <Text className='section-heading'>知识点</Text>
        <View className='handbook-search-panel'>
          <Input
            className='input'
            placeholder='搜索标题、摘要或正文'
            value={searchQuery}
            confirmType='search'
            onInput={event => setSearchQuery(String(event.detail.value || ''))}
          />
          {query ? (
            <Button className='secondary-button' onClick={() => setSearchQuery('')}>清空</Button>
          ) : null}
        </View>
        {entries.length ? (
          <View className='handbook-outline'>
            {filteredEntries.map((item, index) => (
              <View
                className={`handbook-outline-chip ${activeEntry?.id === item.id ? 'active' : ''}`}
                key={item.id}
                onClick={() => selectEntry(item.id)}
              >
                <Text className='handbook-outline-index'>{String(index + 1).padStart(2, '0')}</Text>
                <Text className='handbook-outline-title'>{item.title}</Text>
              </View>
            ))}
          </View>
        ) : null}
        {query && entries.length ? (
          <Text className='row-meta'>找到 {String(filteredEntries.length)} 个知识点</Text>
        ) : null}
        <View className='list-stack handbook-entry-list'>
          {filteredEntries.map(item => {
            const snippet = firstSnippet(item, query);
            return (
              <View
                id={safeEntryDomId(item.id)}
                className={`list-row handbook-entry-row ${activeEntry?.id === item.id ? 'active' : ''}`}
                key={item.id}
              >
                <Text className='row-main'>{item.title}</Text>
                {snippet ? (
                  <View className='handbook-search-snippet'>
                    {highlightParts(snippet, query).map((part, index) => (
                      <Text className={part.hit ? 'handbook-highlight' : ''} key={`${item.id}-${index}`}>
                        {part.text}
                      </Text>
                    ))}
                  </View>
                ) : null}
                {item.summary ? <RichContent content={item.summary} compact muted /> : null}
                <View className='handbook-entry-body'>
                  <RichContent content={item.content || '暂无内容'} compact />
                </View>
              </View>
            );
          })}
        </View>
        {!entries.length ? <View className='empty-state'>当前章节暂无知识点。</View> : null}
        {entries.length && !filteredEntries.length ? <View className='empty-state'>没有找到匹配的知识点。</View> : null}
        {error ? <Text className='error-text'>{error}</Text> : null}
      </View>
    </View>
  );
}
