import { Colors } from '@/constants/Colors';
import { useColorScheme } from '@/hooks/useColorScheme';
import { Ionicons } from '@expo/vector-icons';
import { Image } from 'expo-image';
import React from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import Markdown from 'react-native-markdown-display';
import { ChatMessage, MessageAttachment } from './types';

interface MessageAttachmentComponentProps {
  attachment: MessageAttachment;
  onPreview?: (uri: string) => void;
}

const MessageAttachmentComponent: React.FC<MessageAttachmentComponentProps> = ({
  attachment,
  onPreview
}) => {
  const colorScheme = useColorScheme();
  const theme = Colors[colorScheme ?? 'light'];

  if (attachment.type === 'image') {
    return (
      <TouchableOpacity
        style={styles.imageAttachment}
        onPress={() => onPreview?.(attachment.url)}
        activeOpacity={0.8}
      >
        <Image
          source={{ uri: attachment.url }}
          style={styles.attachmentImage}
          contentFit="cover"
        />
        {attachment.uploadProgress !== undefined && attachment.uploadProgress < 1 && (
          <View style={styles.attachmentProgressOverlay}>
            <Text style={styles.attachmentProgressText}>
              {Math.round(attachment.uploadProgress * 100)}%
            </Text>
          </View>
        )}
        {attachment.uploadError && (
          <View style={styles.attachmentErrorOverlay}>
            <Text style={styles.attachmentErrorText}>上传失败</Text>
          </View>
        )}
      </TouchableOpacity>
    );
  }

  if (attachment.type === 'video') {
    return (
      <View style={styles.videoAttachment}>
        <View style={styles.videoPlaceholder}>
          <Ionicons name="play-circle" size={32} color="#fff" />
          {attachment.filename && (
            <Text style={styles.videoFilename}>{attachment.filename}</Text>
          )}
        </View>
      </View>
    );
  }

  if (attachment.type === 'file') {
    return (
      <View style={styles.fileAttachment}>
        <Ionicons name="document" size={20} color={theme.text} />
        <Text style={[styles.fileFilename, { color: theme.text }]}>
          {attachment.filename || '未知文件'}
        </Text>
      </View>
    );
  }

  return null;
};

interface ChatMessageComponentProps {
  message: ChatMessage;
  onPreviewImage?: (uri: string) => void;
  onChoiceSelect?: (messageId: string, choiceId: string) => void;
  selectedChoices?: Record<string, string>;
  pendingChoiceConfirmation?: Record<string, boolean>;
  isStreaming?: boolean;
  onCancelStream?: () => void;
}

const ChatMessageComponent: React.FC<ChatMessageComponentProps> = ({
  message,
  onPreviewImage,
  onChoiceSelect,
  selectedChoices,
  pendingChoiceConfirmation,
  isStreaming,
  onCancelStream
}) => {
  const colorScheme = useColorScheme();
  const theme = Colors[colorScheme ?? 'light'];

  const isUser = message.role === 'user';
  const isAssistant = message.role === 'assistant';

  return (
    <View style={[styles.row, isUser && styles.userRow]}>
      {isAssistant && (
        <View style={[styles.avatar, { backgroundColor: theme.primary }]}>
          <Text style={styles.avatarText}>AI</Text>
        </View>
      )}

      <View style={[
        styles.bubble,
        {
          backgroundColor: isUser ? theme.primary : theme.surface,
          alignSelf: isUser ? 'flex-end' : 'flex-start',
          maxWidth: '85%',
        }
      ]}>
        {/* 文本内容 */}
        {message.content ? (
          isUser ? (
            <Text style={[styles.bubbleText, { color: theme.onPrimary }]}>
              {message.content}
            </Text>
          ) : (
            <Markdown
              style={{
                body: { color: theme.text, fontSize: 15, lineHeight: 22 },
                paragraph: { marginTop: 2, marginBottom: 2 },
                bullet_list: { marginVertical: 4 },
                ordered_list: { marginVertical: 4 },
                list_item: { flexDirection: 'row' },
                code_inline: {
                  backgroundColor: 'rgba(0,0,0,0.06)',
                  borderRadius: 4,
                  paddingHorizontal: 4,
                  paddingVertical: 2,
                },
                code_block: {
                  backgroundColor: 'rgba(0,0,0,0.06)',
                  borderRadius: 8,
                  paddingHorizontal: 8,
                  paddingVertical: 6,
                },
                fence: {
                  backgroundColor: 'rgba(0,0,0,0.06)',
                  borderRadius: 8,
                  paddingHorizontal: 8,
                  paddingVertical: 6,
                },
                heading1: { fontSize: 20, fontWeight: '800', marginVertical: 6 },
                heading2: { fontSize: 18, fontWeight: '800', marginVertical: 6 },
                heading3: { fontSize: 16, fontWeight: '800', marginVertical: 6 },
                link: { color: '#246BFD' },
              }}
            >
              {message.content}
            </Markdown>
          )
        ) : null}

        {/* 附件 */}
        {message.attachments && message.attachments.length > 0 && (
          <View style={styles.attachmentsContainer}>
            {message.attachments.map((attachment) => (
              <MessageAttachmentComponent
                key={attachment.id}
                attachment={attachment}
                onPreview={onPreviewImage}
              />
            ))}
          </View>
        )}

        {/* 选择选项 */}
        {message.choices && message.choices.length > 0 && (
          <View style={styles.choicesContainer}>
            {message.choices.map((choice) => {
              const isSelected = selectedChoices?.[message.id] === choice.id;
              const isLoading = pendingChoiceConfirmation?.[message.id];
              const isDisabled = isLoading || (selectedChoices?.[message.id] && !isSelected) || false;

              return (
                <TouchableOpacity
                  key={choice.id}
                  style={[
                    styles.choiceButton,
                    !!choice.recommended && styles.choiceButtonRecommended,
                    isSelected && styles.choiceButtonSelected,
                    isDisabled && styles.choiceButtonDisabled,
                  ]}
                  onPress={() => onChoiceSelect?.(message.id, choice.id)}
                  disabled={isDisabled}
                >
                  <View style={styles.choiceContent}>
                    <Text style={[
                      styles.choiceLabel,
                      !!choice.recommended && styles.choiceLabelRecommended,
                      isSelected && styles.choiceLabelSelected,
                      isDisabled && styles.choiceLabelDisabled,
                    ]}>
                      {choice.emoji ? `${choice.emoji} ` : ''}{choice.label}
                    </Text>

                    <View style={styles.choiceStatusContainer}>
                      {!!choice.recommended && !isSelected && (
                        <View style={styles.recommendedBadge}>
                          <Text style={styles.recommendedText}>推荐</Text>
                        </View>
                      )}
                      {isSelected && (
                        <View style={styles.selectedBadge}>
                          <Text style={styles.selectedText}>已选择</Text>
                        </View>
                      )}
                    </View>
                  </View>
                </TouchableOpacity>
              );
            })}
          </View>
        )}

        {/* 流式回复控制 */}
        {isAssistant && isStreaming && !message.content && (
          <View style={styles.streamingContainer}>
            <Text style={[styles.bubbleText, { color: theme.text }]}>正在思考...</Text>
            <TouchableOpacity
              style={styles.cancelStreamBtn}
              onPress={onCancelStream}
            >
              <Ionicons name="stop" size={12} color="#FF4444" />
              <Text style={styles.cancelStreamText}>停止</Text>
            </TouchableOpacity>
          </View>
        )}
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    alignItems: 'flex-end',
    gap: 8,
    marginVertical: 6,
  },
  userRow: {
    justifyContent: 'flex-end',
  },
  avatar: {
    width: 28,
    height: 28,
    borderRadius: 14,
    alignItems: 'center',
    justifyContent: 'center',
  },
  avatarText: {
    color: '#192126',
    fontSize: 12,
    fontWeight: '800',
  },
  bubble: {
    paddingHorizontal: 12,
    paddingVertical: 10,
    borderRadius: 16,
  },
  bubbleText: {
    fontSize: 15,
    lineHeight: 22,
  },
  attachmentsContainer: {
    marginTop: 8,
    gap: 6,
  },
  imageAttachment: {
    borderRadius: 12,
    overflow: 'hidden',
    position: 'relative',
  },
  attachmentImage: {
    width: '100%',
    minHeight: 120,
    maxHeight: 200,
    borderRadius: 12,
  },
  attachmentProgressOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: 'rgba(0,0,0,0.4)',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 12,
  },
  attachmentProgressText: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '600',
  },
  attachmentErrorOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: 'rgba(255,0,0,0.4)',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 12,
  },
  attachmentErrorText: {
    color: '#fff',
    fontSize: 12,
    fontWeight: '600',
  },
  videoAttachment: {
    borderRadius: 12,
    overflow: 'hidden',
    backgroundColor: 'rgba(0,0,0,0.1)',
  },
  videoPlaceholder: {
    height: 120,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(0,0,0,0.6)',
  },
  videoFilename: {
    color: '#fff',
    fontSize: 12,
    marginTop: 4,
    textAlign: 'center',
  },
  fileAttachment: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 12,
    backgroundColor: 'rgba(0,0,0,0.06)',
    borderRadius: 8,
    gap: 8,
  },
  fileFilename: {
    flex: 1,
    fontSize: 14,
  },
  choicesContainer: {
    gap: 8,
    width: '100%',
    marginTop: 8,
  },
  choiceButton: {
    backgroundColor: 'rgba(255,255,255,0.9)',
    borderWidth: 1,
    borderColor: '#7a5af84d',
    borderRadius: 12,
    padding: 12,
    width: '100%',
    minWidth: 0,
  },
  choiceButtonRecommended: {
    borderColor: '#7a5af899',
    backgroundColor: '#7a5af81a',
  },
  choiceButtonSelected: {
    borderColor: '#19b36e',
    backgroundColor: '#19b36e33',
    borderWidth: 2,
  },
  choiceButtonDisabled: {
    backgroundColor: 'rgba(0,0,0,0.05)',
    borderColor: 'rgba(0,0,0,0.1)',
    opacity: 0.5,
  },
  choiceContent: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    width: '100%',
  },
  choiceLabel: {
    fontSize: 15,
    fontWeight: '600',
    color: '#192126',
    flex: 1,
    flexWrap: 'wrap',
  },
  choiceLabelRecommended: {
    color: '#19b36e',
  },
  choiceLabelSelected: {
    color: '#19b36e',
    fontWeight: '700',
  },
  choiceLabelDisabled: {
    color: '#687076',
  },
  choiceStatusContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  recommendedBadge: {
    backgroundColor: '#7a5af8cc',
    borderRadius: 6,
    paddingHorizontal: 8,
    paddingVertical: 2,
  },
  recommendedText: {
    fontSize: 12,
    fontWeight: '700',
    color: '#19b36e',
  },
  selectedBadge: {
    backgroundColor: '#19b36e',
    borderRadius: 6,
    paddingHorizontal: 8,
    paddingVertical: 2,
  },
  selectedText: {
    fontSize: 12,
    fontWeight: '700',
    color: '#FFFFFF',
  },
  streamingContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    gap: 12,
  },
  cancelStreamBtn: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 4,
    paddingHorizontal: 8,
    paddingVertical: 4,
    borderRadius: 12,
    backgroundColor: 'rgba(255,68,68,0.1)',
    borderWidth: 1,
    borderColor: 'rgba(255,68,68,0.3)',
  },
  cancelStreamText: {
    fontSize: 12,
    fontWeight: '600',
    color: '#FF4444',
  },
});

export default ChatMessageComponent;