/**
 * PostMentionInput - 帖子内容输入框（支持 @提及）
 * 复用关注列表加载逻辑
 * 检测输入中的 @ 字符，弹出关注者列表供选择
 */

import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
  View,
  TextInput,
  ScrollView,
  TouchableOpacity,
  StyleSheet,
  Platform,
} from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons';

import Text from '../common/Text';
import Avatar from '../common/Avatar';
import { useAppColors, spacing, fontSizes, borderRadius } from '../../theme';
import { useAuthStore } from '../../stores';
import { authService } from '../../services/auth';
import { postService } from '../../services/post/postService';
import { MessageSegment, AtSegmentData } from '../../types';

interface MentionUser {
  id: string;
  nickname: string;
  avatar: string | null;
}

interface SuggestPost {
  id: string;
  title: string;
  channel?: string;
}

type SuggestionMode = 'none' | 'mention' | 'postref';

interface PostMentionInputProps {
  value: string;
  onChangeText: (text: string) => void;
  onSegmentsChange: (segments: MessageSegment[]) => void;
  placeholder?: string;
  maxLength?: number;
  style?: any;
  minHeight?: number;
  autoExpand?: boolean;
  onPostRefPasted?: (postId: string, title: string) => void;
  onSubmitEditing?: () => void;
  returnKeyType?: 'default' | 'send' | 'done';
}

const PostMentionInput: React.FC<PostMentionInputProps> = ({
  value,
  onChangeText,
  onSegmentsChange,
  placeholder = '说点什么...',
  maxLength = 2000,
  style,
  minHeight = 100,
  autoExpand = false,
  onPostRefPasted,
  onSubmitEditing,
  returnKeyType = 'default',
}) => {
  const colors = useAppColors();
  const currentUser = useAuthStore(s => s.currentUser);
  const [followingUsers, setFollowingUsers] = useState<MentionUser[]>([]);
  const [suggestPosts, setSuggestPosts] = useState<SuggestPost[]>([]);
  const [suggestionMode, setSuggestionMode] = useState<SuggestionMode>('none');
  const [mentionQuery, setMentionQuery] = useState('');
  const [mentionStartIndex, setMentionStartIndex] = useState(-1);
  const [loaded, setLoaded] = useState(false);
  const [postSearchTimer, setPostSearchTimer] = useState<ReturnType<typeof setTimeout> | null>(null);
  const inputRef = useRef<TextInput>(null);

  useEffect(() => {
    if (!loaded && currentUser?.id) {
      loadFollowing();
      setLoaded(true);
    }
  }, [currentUser?.id, loaded]);

  const loadFollowing = async () => {
    if (!currentUser?.id) return;
    try {
      const list = await authService.getFollowingList(currentUser.id, 1, 200);
      setFollowingUsers(
        list.map(u => ({
          id: u.id,
          nickname: u.nickname || u.username || '',
          avatar: u.avatar || null,
        }))
      );
    } catch (_) {
      // ignore
    }
  };

  const filteredUsers = followingUsers.filter(u =>
    u.nickname.toLowerCase().includes(mentionQuery.toLowerCase())
  );

  const activeMentions = useRef(new Map<number, { endIndex: number; userId: string; nickname: string }>());
  const segmentsRef = useRef<MessageSegment[]>([]);

  const rebuildSegments = useCallback(
    (text: string) => {
      const mentions = activeMentions.current;
      if (mentions.size === 0) {
        onSegmentsChange(text.trim() ? [{ type: 'text', data: { text } }] : []);
        return;
      }

      const segments: MessageSegment[] = [];
      const sorted = Array.from(mentions.entries()).sort((a, b) => a[0] - b[0]);
      let lastEnd = 0;

      for (const [startIdx, mention] of sorted) {
        if (startIdx > lastEnd) {
          segments.push({ type: 'text', data: { text: text.slice(lastEnd, startIdx) } });
        }
        segments.push({
          type: 'at',
          data: { user_id: mention.userId, nickname: mention.nickname } as AtSegmentData,
        });
        lastEnd = mention.endIndex;
      }

      if (lastEnd < text.length) {
        segments.push({ type: 'text', data: { text: text.slice(lastEnd) } });
      }

      onSegmentsChange(segments);
    },
    [onSegmentsChange]
  );

  const handleChangeText = useCallback(
    (text: string) => {
      onChangeText(text);

      const cursorPos = text.length;

      // Check for # trigger (post ref search)
      let hashStart = -1;
      for (let i = cursorPos - 1; i >= 0; i--) {
        if (text[i] === '#') {
          hashStart = i;
          break;
        }
        if (text[i] === ' ' || text[i] === '\n') {
          break;
        }
      }

      if (hashStart >= 0) {
        const query = text.slice(hashStart + 1, cursorPos);
        if (query.length >= 1 && !query.includes(' ') && !query.includes('\n')) {
          if (postSearchTimer) {
            clearTimeout(postSearchTimer);
          }
          const timer = setTimeout(async () => {
            try {
              const results = await postService.suggestPosts(query, 8);
              setSuggestPosts(results);
              setSuggestionMode('postref');
              setMentionStartIndex(hashStart);
            } catch {
              // ignore
            }
          }, 300);
          setPostSearchTimer(timer);
          return;
        }
      }

      // Check for @ trigger (mention)
      let atStart = -1;
      for (let i = cursorPos - 1; i >= 0; i--) {
        if (text[i] === '@') {
          atStart = i;
          break;
        }
        if (text[i] === ' ' || text[i] === '\n') {
          break;
        }
      }

      if (atStart >= 0) {
        const query = text.slice(atStart + 1, cursorPos);
        if (!query.includes(' ') && !query.includes('\n')) {
          setMentionQuery(query);
          setMentionStartIndex(atStart);
          setSuggestionMode('mention');
          return;
        }
      }

      setSuggestionMode('none');
      rebuildSegments(text);
    },
    [onChangeText, rebuildSegments, postSearchTimer],
  );

  const handleSelectMention = useCallback(
    (mentionUser: MentionUser) => {
      if (mentionStartIndex < 0) return;

      const before = value.slice(0, mentionStartIndex);
      const mentionText = `@${mentionUser.nickname} `;
      const newText = before + mentionText;

      activeMentions.current.set(mentionStartIndex, {
        endIndex: before.length + mentionText.length,
        userId: mentionUser.id,
        nickname: mentionUser.nickname,
      });

      onChangeText(newText);
      setSuggestionMode('none');
      setMentionQuery('');
      setMentionStartIndex(-1);

      rebuildSegments(newText);

      inputRef.current?.focus();
    },
    [value, mentionStartIndex, onChangeText, rebuildSegments],
  );

  const handleSelectPost = useCallback(
    (post: SuggestPost) => {
      if (mentionStartIndex < 0) return;

      const before = value.slice(0, mentionStartIndex);
      const refText = `#${post.title} `;
      const newText = before + refText;

      onChangeText(newText);
      setSuggestionMode('none');
      setSuggestPosts([]);
      setMentionStartIndex(-1);

      if (onPostRefPasted) {
        onPostRefPasted(post.id, post.title);
      }

      rebuildSegments(newText);

      inputRef.current?.focus();
    },
    [value, mentionStartIndex, onChangeText, rebuildSegments, onPostRefPasted],
  );

  const renderMentionItem = ({ item }: { item: MentionUser }) => (
    <TouchableOpacity
      style={[styles.mentionItem, { borderBottomColor: colors.divider }]}
      onPress={() => handleSelectMention(item)}
      activeOpacity={0.7}
    >
      <Avatar source={item.avatar} size={36} name={item.nickname} />
      <View style={styles.mentionInfo}>
        <Text style={[styles.mentionName, { color: colors.text.primary }]}>
          {item.nickname}
        </Text>
        <Text style={[styles.mentionHint, { color: colors.text.hint }]}>
          点击提及
        </Text>
      </View>
      <MaterialCommunityIcons name="at" size={18} color={colors.primary.main} />
    </TouchableOpacity>
  );

  return (
    <View style={[styles.container, style]}>
      <TextInput
        ref={inputRef}
        value={value}
        onChangeText={handleChangeText}
        placeholder={placeholder}
        placeholderTextColor={colors.text.hint}
        maxLength={maxLength}
        multiline
        textAlignVertical="top"
        scrollEnabled={!autoExpand}
        returnKeyType={returnKeyType}
        onSubmitEditing={onSubmitEditing}
        blurOnSubmit={false}
        style={[
          styles.input,
          autoExpand && styles.inputAutoExpand,
          {
            color: colors.text.primary,
            backgroundColor: autoExpand ? 'transparent' : colors.background.default,
            minHeight,
          },
        ]}
      />

      {suggestionMode === 'mention' && filteredUsers.length > 0 && (
        <View style={[styles.mentionPanel, { backgroundColor: colors.background.paper, borderColor: colors.divider }]}>
          <ScrollView
            keyboardShouldPersistTaps="handled"
            nestedScrollEnabled
            style={styles.mentionList}
          >
            {filteredUsers.map(item => (
              <React.Fragment key={item.id}>
                {renderMentionItem({ item })}
              </React.Fragment>
            ))}
          </ScrollView>
        </View>
      )}

      {suggestionMode === 'mention' && filteredUsers.length === 0 && (
        <View style={[styles.mentionPanel, { backgroundColor: colors.background.paper, borderColor: colors.divider }]}>
          <Text style={[styles.emptyText, { color: colors.text.hint }]}>
            没有找到匹配的关注用户
          </Text>
        </View>
      )}

      {suggestionMode === 'postref' && suggestPosts.length > 0 && (
        <View style={[styles.mentionPanel, { backgroundColor: colors.background.paper, borderColor: colors.divider }]}>
          <ScrollView
            keyboardShouldPersistTaps="handled"
            nestedScrollEnabled
            style={styles.mentionList}
          >
            {suggestPosts.map(item => (
              <TouchableOpacity
                key={item.id}
                style={[styles.mentionItem, { borderBottomColor: colors.divider }]}
                onPress={() => handleSelectPost(item)}
                activeOpacity={0.7}
              >
                <MaterialCommunityIcons name="file-document-outline" size={18} color={colors.primary.main} />
                <View style={styles.mentionInfo}>
                  <Text style={[styles.mentionName, { color: colors.text.primary }]} numberOfLines={1}>
                    {item.title}
                  </Text>
                  <Text style={[styles.mentionHint, { color: colors.text.hint }]}>
                    点击引用帖子
                  </Text>
                </View>
              </TouchableOpacity>
            ))}
          </ScrollView>
        </View>
      )}

      {suggestionMode === 'postref' && suggestPosts.length === 0 && (
        <View style={[styles.mentionPanel, { backgroundColor: colors.background.paper, borderColor: colors.divider }]}>
          <Text style={[styles.emptyText, { color: colors.text.hint }]}>
            没有找到匹配的帖子
          </Text>
        </View>
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
  },
  input: {
    fontSize: fontSizes.md,
    padding: spacing.sm,
    borderRadius: borderRadius.md,
    minHeight: 100,
    textAlignVertical: 'top' as const,
  },
  inputAutoExpand: {
    borderRadius: 0,
    paddingHorizontal: 0,
    paddingTop: spacing.sm,
    paddingBottom: spacing.sm,
  },
  mentionPanel: {
    borderWidth: 1,
    borderRadius: borderRadius.md,
    maxHeight: 200,
    marginTop: spacing.xs,
  },
  mentionList: {
    maxHeight: 200,
  },
  mentionItem: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: spacing.md,
    paddingVertical: spacing.sm,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  mentionInfo: {
    flex: 1,
    marginLeft: spacing.sm,
    justifyContent: 'center',
  },
  mentionName: {
    fontSize: fontSizes.md,
    fontWeight: '500',
  },
  mentionHint: {
    fontSize: fontSizes.xs,
    marginTop: 2,
  },
  emptyText: {
    fontSize: fontSizes.sm,
    padding: spacing.md,
    textAlign: 'center',
  },
});

export default PostMentionInput;