import { chat as chatNs } from '@chat-app/shared';
import type { DecryptedMessage, MessageReaction } from '@chat-app/shared/chat';
import { Pressable, StyleSheet, Text, View } from 'react-native';

import { colors } from '../theme/colors';
import { AttachmentImage } from './AttachmentImage';
import { ReactionPills } from './ReactionPills';

interface Props {
  message: DecryptedMessage;
  mine: boolean;
  senderName: string;
  time: string;
  parent: DecryptedMessage | null;
  parentSenderName: string;
  reactions: MessageReaction[];
  myUserId: string | null;
  ownDeviceId: string | null;
  ownPrivateKey: Uint8Array | null;
  onLongPress: () => void;
  onToggleReaction: (emoji: string) => void;
}

// Single message bubble. Renders, in order:
//   * Reply quote (when this message has a replyToId).
//   * Body text (or "Nachricht gelöscht" placeholder).
//   * Image attachment (max 1 in Phase 2 — first one wins).
//   * Reaction pills.
// Long-press surfaces the MessageActionsSheet via the onLongPress callback.
export function MessageBubble({
  message,
  mine,
  senderName,
  time,
  parent,
  parentSenderName,
  reactions,
  myUserId,
  ownDeviceId,
  ownPrivateKey,
  onLongPress,
  onToggleReaction,
}: Props) {
  const deleted = message.deletedAt !== null;
  const parsed = chatNs.parseMessagePayload(message.plaintext);
  const text = parsed.kind === 'text' ? parsed.text : '';
  const attachments = parsed.kind === 'text' ? parsed.attachments : [];
  const firstImage = attachments.find((a) => a.mimeType.startsWith('image/'));

  return (
    <View style={[styles.wrap, mine ? styles.wrapMine : styles.wrapOther]}>
      <Pressable
        onLongPress={onLongPress}
        delayLongPress={250}
        style={[styles.bubble, mine ? styles.bubbleMine : styles.bubbleOther]}
      >
        {!mine && !deleted && <Text style={styles.sender}>{senderName}</Text>}

        {message.replyToId && (
          <View style={[styles.replyQuote, mine ? styles.replyQuoteMine : null]}>
            <Text style={styles.replyAuthor}>{parent ? parentSenderName : 'Original'}</Text>
            <Text style={styles.replyBody} numberOfLines={2}>
              {parent
                ? quotedPreview(parent)
                : '↩ Original-Nachricht außerhalb dieses Fensters'}
            </Text>
          </View>
        )}

        {deleted ? (
          <Text style={styles.deleted}>Nachricht gelöscht</Text>
        ) : (
          <>
            {text.length > 0 && <Text style={styles.body}>{text}</Text>}
            {firstImage && ownDeviceId && ownPrivateKey && (
              <AttachmentImage
                handle={firstImage}
                ownDeviceId={ownDeviceId}
                ownPrivateKey={ownPrivateKey}
              />
            )}
          </>
        )}

        <Text style={styles.time}>{time}</Text>
      </Pressable>

      {!deleted && (
        <ReactionPills
          reactions={reactions}
          myUserId={myUserId}
          onToggle={onToggleReaction}
        />
      )}
    </View>
  );
}

function quotedPreview(m: DecryptedMessage): string {
  if (m.deletedAt) return '[gelöscht]';
  const parsed = chatNs.parseMessagePayload(m.plaintext);
  if (parsed.kind === 'text') {
    if (parsed.text.length > 0) return parsed.text;
    if (parsed.attachments.length > 0) return '📎 Anhang';
  }
  return '…';
}

const styles = StyleSheet.create({
  wrap: { marginVertical: 4, maxWidth: '78%' },
  wrapMine: { alignSelf: 'flex-end', alignItems: 'flex-end' },
  wrapOther: { alignSelf: 'flex-start', alignItems: 'flex-start' },
  bubble: { padding: 10, borderRadius: 14 },
  bubbleMine: { backgroundColor: colors.accent },
  bubbleOther: { backgroundColor: colors.surface, borderColor: colors.border, borderWidth: 1 },
  sender: { color: colors.textMuted, fontSize: 11, fontWeight: '600', marginBottom: 4 },
  body: { color: colors.text, fontSize: 15, lineHeight: 20 },
  time: { color: colors.textDim, fontSize: 10, marginTop: 4, textAlign: 'right' },
  deleted: { color: colors.textMuted, fontSize: 14, fontStyle: 'italic' },
  replyQuote: {
    borderLeftWidth: 3,
    borderLeftColor: colors.accent,
    paddingLeft: 8,
    paddingVertical: 4,
    marginBottom: 6,
    backgroundColor: colors.bg,
    borderRadius: 4,
  },
  replyQuoteMine: { backgroundColor: 'rgba(0,0,0,0.18)', borderLeftColor: colors.text },
  replyAuthor: { color: colors.textMuted, fontSize: 11, fontWeight: '700' },
  replyBody: { color: colors.text, fontSize: 13, opacity: 0.85 },
});
