import type {DmMessage} from '@crumbs/core/schemas'
import {Pressable, View} from 'react-native'

import {Text} from '@/components/ui/typography'
import {showEntrySyncMenu} from '@/lib/sync-menu'
import {atoms as a, useTheme} from '@/sprinkles'
import {useEntrySyncState} from '@/stores/outbox'

// plain-text chat bubble; dms deliberately render no mentions
export const MessageBubble = ({
  message,
  mine,
}: {
  message: DmMessage
  mine: boolean
}) => {
  const t = useTheme()
  // the message id is its outbox entry id, so this reflects this bubble's own
  // send — 'synced' the moment it lands, 'failed' if it dead-letters
  const sync = useEntrySyncState(message.id)
  const failed = mine && sync === 'failed'
  const content = (
    <View style={{maxWidth: '75%'}}>
      <View
        accessibilityLabel={mine ? 'Your message' : 'Their message'}
        style={[
          a.px_md,
          a.py_xs,
          a.rounded_lg,
          mine
            ? {backgroundColor: t.palette.primary_500}
            : t.atoms.bg_contrast_50,
        ]}
      >
        <Text
          emoji
          style={[
            a.text_md,
            a.leading_normal,
            mine && {color: t.palette.white},
          ]}
        >
          {message.text}
        </Text>
      </View>
      {mine && sync !== 'synced' && (
        <Text
          style={[
            a.text_xs,
            a.pt_xs,
            a.text_right,
            failed
              ? {color: t.palette.negative_500}
              : t.atoms.text_contrast_medium,
          ]}
        >
          {failed ? 'Not sent' : 'Sending…'}
        </Text>
      )}
    </View>
  )
  return (
    <View
      style={[a.flex_row, mine ? a.justify_end : a.justify_start]}
    >
      {failed ? (
        // recovery affordance for a dead-lettered send — a dead head also
        // blocks every later send in the conversation, so it must be
        // actionable in place, like the crumb/trail failed badges. wrapped
        // only when failed: a pressable would subsume the bubble's inner
        // text into one a11y node, hiding the 'Sending…' state
        <Pressable
          accessibilityRole="button"
          accessibilityLabel={`Message not sent: ${message.text}`}
          accessibilityHint="Retry or discard"
          onPress={() => showEntrySyncMenu(message.id)}
        >
          {content}
        </Pressable>
      ) : (
        content
      )}
    </View>
  )
}
