/**
 * PostContentRenderer - 帖子内容渲染器
 * 根据 segments 渲染富文本内容（@提及、投票、内嵌图片等）
 * 降级：如果 segments 为空但 content 非空，直接显示纯文本
 */

import React, { useMemo } from 'react';
import { View, TouchableOpacity, StyleSheet, TextStyle, StyleProp, Dimensions } from 'react-native';
import { Image as ExpoImage } from 'expo-image';

import Text from '../common/Text';
import HighlightText from '../common/HighlightText';
import { useAppColors } from '../../theme';
import {
  MessageSegment,
  AtSegmentData,
  VoteSegmentData,
  PostRefSegmentData,
  ImageSegmentData,
  partitionSegments,
} from '../../types';
import PostRefCard from './PostRefCard';

interface PostContentRendererProps {
  content?: string;
  segments?: MessageSegment[];
  numberOfLines?: number;
  onMentionPress?: (userId: string) => void;
  onPostRefPress?: (postId: string) => void;
  onImagePress?: (url: string) => void;
  style?: any;
  textStyle?: any;
  highlightKeyword?: string;
  highlightStyle?: StyleProp<TextStyle>;
}

const SCREEN_WIDTH = Dimensions.get('window').width;
const INLINE_IMAGE_MAX_WIDTH = SCREEN_WIDTH - 32;

function hasInlineImages(segments?: MessageSegment[]): boolean {
  if (!segments) return false;
  return segments.some(s => s.type === 'image');
}

const PostContentRenderer: React.FC<PostContentRendererProps> = ({
  content,
  segments,
  numberOfLines,
  onMentionPress,
  onPostRefPress,
  onImagePress,
  style,
  textStyle,
  highlightKeyword,
  highlightStyle,
}) => {
  const colors = useAppColors();
  const hasImages = hasInlineImages(segments);

  if (!segments || segments.length === 0) {
    return (
      <Text numberOfLines={numberOfLines} selectable style={textStyle}>
        {highlightKeyword && content ? (
          <HighlightText text={content} keyword={highlightKeyword} style={highlightStyle} />
        ) : (
          content || ''
        )}
      </Text>
    );
  }

  const hasComplexContent = hasImages ||
    segments.some(s => s.type === 'vote' || s.type === 'post_ref');

  if (!hasComplexContent || (numberOfLines && !hasImages)) {
    const elements: React.ReactNode[] = [];
    let keyIndex = 0;

    for (const segment of segments) {
      const key = `seg_${keyIndex++}`;
      switch (segment.type) {
        case 'text': {
          const text = segment.data?.text || segment.data?.content || '';
          if (text) {
            elements.push(
              <Text key={key} selectable style={textStyle}>
                {highlightKeyword ? (
                  <HighlightText text={text} keyword={highlightKeyword} style={highlightStyle} />
                ) : (
                  text
                )}
              </Text>
            );
          }
          break;
        }
        case 'at': {
          const atData = segment.data as AtSegmentData;
          const userId = atData?.user_id;
          const isAtAll = userId === 'all';
          const displayName = atData?.nickname || (isAtAll ? '所有人' : '某人');
          elements.push(
            <Text
              key={key}
              selectable
              style={[
                textStyle,
                { color: colors.primary.main, fontWeight: '500' },
              ]}
            >
              @{displayName}{' '}
            </Text>
          );
          break;
        }
        case 'image':
        case 'link':
        case 'face':
        default:
          break;
      }
    }

    if (elements.length === 0) {
      return (
        <Text numberOfLines={numberOfLines} selectable style={textStyle}>
          {highlightKeyword && content ? (
            <HighlightText text={content} keyword={highlightKeyword} style={highlightStyle} />
          ) : (
            content || ''
          )}
        </Text>
      );
    }

    if (numberOfLines) {
      return (
        <View style={style}>
          <Text numberOfLines={numberOfLines} selectable style={textStyle}>
            {elements}
          </Text>
        </View>
      );
    }

    return <View style={[styles.container, style]}>{elements}</View>;
  }

  const chunks = partitionSegments(segments);

  return (
    <View style={[styles.chunkContainer, style]}>
      {chunks.map((chunk, i) => {
        if (chunk.kind === 'inline') {
          return (
            <Text key={`inl-${i}`} selectable style={textStyle}>
              {chunk.parts.map((segment, j) => {
                const segKey = `inl-${i}-${j}`;
                switch (segment.type) {
                  case 'text': {
                    const text = segment.data?.text || segment.data?.content || '';
                    return highlightKeyword ? (
                      <HighlightText key={segKey} text={text} keyword={highlightKeyword} style={highlightStyle} />
                    ) : (
                      <Text key={segKey}>{text}</Text>
                    );
                  }
                  case 'at': {
                    const atData = segment.data as AtSegmentData;
                    const userId = atData?.user_id;
                    const displayName = atData?.nickname || (userId === 'all' ? '所有人' : '某人');
                    return (
                      <Text
                        key={segKey}
                        style={[textStyle, { color: colors.primary.main, fontWeight: '500' }]}
                        onPress={() => onMentionPress?.(userId)}
                      >
                        @{displayName}{' '}
                      </Text>
                    );
                  }
                  default:
                    return null;
                }
              })}
            </Text>
          );
        }

        if (chunk.kind === 'images') {
          return (
            <View key={`imgs-${i}`} style={styles.inlineImagesContainer}>
              {chunk.parts.map((segment, j) => {
                const imgData = segment.data as ImageSegmentData;
                const url = imgData?.url || '';
                if (!url) return null;

                const aspectRatio = imgData.width && imgData.height
                  ? imgData.width / imgData.height
                  : 4 / 3;
                const displayWidth = INLINE_IMAGE_MAX_WIDTH;
                const displayHeight = displayWidth / aspectRatio;

                return (
                  <TouchableOpacity
                    key={`img-${i}-${j}`}
                    activeOpacity={0.9}
                    onPress={() => onImagePress?.(url)}
                    style={j < chunk.parts.length - 1 ? styles.imageSpacing : undefined}
                  >
                    <ExpoImage
                      source={{ uri: url }}
                      style={{
                        width: displayWidth,
                        height: displayHeight,
                        borderRadius: 8,
                      }}
                      contentFit="cover"
                      cachePolicy="memory-disk"
                      transition={200}
                    />
                  </TouchableOpacity>
                );
              })}
            </View>
          );
        }

        const { segment } = chunk;
        switch (segment.type) {
          case 'vote': {
            const voteData = segment.data as VoteSegmentData;
            if (!voteData?.options?.length) return null;
            return (
              <View key={`blk-${i}`} style={[styles.voteBlock, { borderColor: colors.divider }]}>
                <Text style={[styles.voteTitle, { color: colors.text.secondary }]}>
                  投票（{voteData.options.length} 个选项）
                </Text>
                {voteData.options.map((opt, k) => (
                  <Text key={`vote_opt_${k}`} selectable style={[styles.voteOption, { color: colors.text.primary }]}>
                    {k + 1}. {opt.content}
                  </Text>
                ))}
              </View>
            );
          }
          case 'post_ref': {
            const refData = segment.data as PostRefSegmentData;
            return (
              <PostRefCard
                key={`blk-${i}`}
                data={refData}
                compact={false}
                onPress={onPostRefPress}
              />
            );
          }
          default:
            return null;
        }
      })}
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    alignItems: 'flex-start',
  },
  chunkContainer: {
    flexDirection: 'column',
  },
  inlineImagesContainer: {
    marginVertical: 8,
  },
  imageSpacing: {
    marginBottom: 6,
  },
  voteBlock: {
    width: '100%',
    borderWidth: 1,
    borderRadius: 8,
    padding: 10,
    marginTop: 4,
    marginBottom: 4,
  },
  voteTitle: {
    fontSize: 13,
    marginBottom: 6,
  },
  voteOption: {
    fontSize: 14,
    paddingVertical: 2,
  },
});

export default PostContentRenderer;
