import React, { useState, useCallback, useRef, useEffect } from 'react';
import {
  View,
  TextInput,
  ScrollView,
  TouchableOpacity,
  StyleSheet,
} 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 type { TextBlock } from './blockEditorTypes';

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

interface TextBlockInputProps {
  block: TextBlock;
  isActive: boolean;
  placeholder: string;
  maxLength: number;
  onTextChange: (blockId: string, text: string, mentions: Map<number, { endIndex: number; userId: string; nickname: string }>) => void;
  onFocusBlock: (blockId: string) => void;
  onSelectMention: (blockId: string, userId: string, nickname: string, mentionStartIndex: number) => void;
  inputRef: (ref: TextInput | null) => void;
  style?: any;
  minHeight?: number;
}

const TextBlockInput: React.FC<TextBlockInputProps> = ({
  block,
  isActive,
  placeholder,
  maxLength,
  onTextChange,
  onFocusBlock,
  onSelectMention,
  inputRef,
  style,
  minHeight,
}) => {
  const colors = useAppColors();
  const currentUser = useAuthStore(s => s.currentUser);
  const [followingUsers, setFollowingUsers] = useState<MentionUser[]>([]);
  const [loaded, setLoaded] = useState(false);
  const [suggestionMode, setSuggestionMode] = useState<'none' | 'mention'>('none');
  const [mentionQuery, setMentionQuery] = useState('');
  const [mentionStartIndex, setMentionStartIndex] = useState(-1);
  const [selection, setSelection] = useState({ start: 0, end: 0 });

  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 handleChangeText = useCallback(
    (newText: string) => {
      const cursorPos = newText.length;

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

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

      // Update mentions when text changes: remap existing mentions
      const newMentions = new Map<number, { endIndex: number; userId: string; nickname: string }>();
      // Simple approach: only keep mentions tracked by this block's own activeMentions
      // The parent handles the canonical mentions state
      block.activeMentions.forEach((mention, start) => {
        if (start < newText.length) {
          const mentionText = `@${mention.nickname} `;
          const expectedEnd = start + mentionText.length;
          // Check if the mention text is still intact
          if (newText.slice(start, expectedEnd) === mentionText) {
            newMentions.set(start, { ...mention, endIndex: expectedEnd });
          }
        }
      });

      onTextChange(block.id, newText, newMentions);
    },
    [block.id, block.activeMentions, onTextChange],
  );

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

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

      const newMentions = new Map(block.activeMentions);
      newMentions.set(mentionStartIndex, {
        endIndex: before.length + mentionText.length,
        userId: mentionUser.id,
        nickname: mentionUser.nickname,
      });

      // Also remove any mention that was partially covered
      const toRemove: number[] = [];
      newMentions.forEach((m, start) => {
        if (start !== mentionStartIndex && start >= mentionStartIndex && start < before.length + mentionText.length) {
          toRemove.push(start);
        }
      });
      toRemove.forEach(k => newMentions.delete(k));

      onTextChange(block.id, newText, newMentions);
      setSuggestionMode('none');
      setMentionQuery('');
      setMentionStartIndex(-1);

      onSelectMention(block.id, mentionUser.id, mentionUser.nickname, mentionStartIndex);
    },
    [block.id, block.text, mentionStartIndex, onTextChange, onSelectMention],
  );

  return (
    <View>
      <TextInput
        ref={inputRef}
        value={block.text}
        onChangeText={handleChangeText}
        placeholder={placeholder}
        placeholderTextColor={colors.text.hint}
        maxLength={maxLength}
        multiline
        textAlignVertical="top"
        scrollEnabled={false}
        onSelectionChange={(e) => setSelection(e.nativeEvent.selection)}
        onFocus={() => onFocusBlock(block.id)}
        style={[
          styles.input,
          {
            color: colors.text.primary,
            minHeight: minHeight,
          },
          style,
        ]}
      />

      {suggestionMode === 'mention' && isActive && filteredUsers.length > 0 && (
        <View style={[styles.mentionPanel, { backgroundColor: colors.background.paper, borderColor: colors.divider }]}>
          <ScrollView
            keyboardShouldPersistTaps="handled"
            nestedScrollEnabled
            style={styles.mentionList}
          >
            {filteredUsers.map(item => (
              <TouchableOpacity
                key={item.id}
                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>
            ))}
          </ScrollView>
        </View>
      )}

      {suggestionMode === 'mention' && isActive && filteredUsers.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({
  input: {
    fontSize: fontSizes.md,
    paddingHorizontal: 0,
    paddingVertical: 0,
    textAlignVertical: 'top' as const,
  },
  mentionPanel: {
    borderWidth: 1,
    borderRadius: borderRadius.md,
    maxHeight: 200,
    marginHorizontal: spacing.sm,
  },
  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 TextBlockInput;