'use client';
import { FunctionComponent } from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { AppIcon } from '@/components/common';
import type { TicketMessage } from '@/services/tickets/types';

export interface MessageBubbleProps {
  message: TicketMessage;
  /** Translated author label (only shown for others' messages — mine is obvious). */
  authorLabel: string;
  /** Renders the author label above the bubble — only the first bubble of a consecutive same-author group. */
  showAuthorLabel: boolean;
  /** Pre-formatted **hh:mm** — the full date lives on the thread's date separator, not the bubble. */
  timeLabel: string;
  /** "در حال ارسال…" — shown while an optimistic message is still sending (in place of the time). */
  sendingLabel: string;
  /** "پیام ارسال نشد" — shown in place of the time when a send has failed (§3.3). */
  failedLabel: string;
  /** «تلاش مجدد» — re-mutates with the same `clientMessageId` (retry-in-place, never a duplicate bubble). */
  retryLabel: string;
  /** Discards the failed bubble and restores its text to the composer draft. */
  discardLabel: string;
  onRetry?: () => void;
  onDiscard?: () => void;
}

/**
 * One message bubble in a ticket thread. **Mine vs theirs** drives side + color and **mirrors for RTL**
 * automatically (`justifyContent: flex-end` resolves to the inline-end — left in RTL). A pending optimistic
 * send shows the "sending" state in place of the timestamp. On **failure** the bubble stays in place
 * (`sendStatus: 'failed'`, error-token accented, `role="alert"` so screen readers are told) with a retry
 * chip (re-mutates the same `clientMessageId` — never a duplicate) and a discard action that restores the
 * typed text to the composer — the invariant that survives any mechanism change: a failure never loses
 * typed text. Never renders any internal-note content or styling (there is no internal message in the user
 * view — §5).
 * @component MessageBubble
 */
const MessageBubble: FunctionComponent<MessageBubbleProps> = ({
  message,
  authorLabel,
  showAuthorLabel,
  timeLabel,
  sendingLabel,
  failedLabel,
  retryLabel,
  discardLabel,
  onRetry,
  onDiscard,
}) => {
  const isMine = message.isMine;
  const sending = message.sendStatus === 'sending';
  const failed = message.sendStatus === 'failed';

  return (
    <Box
      data-testid="message-bubble"
      data-mine={isMine ? 'true' : 'false'}
      data-send-status={message.sendStatus}
      role={failed ? 'alert' : undefined}
      sx={{ display: 'flex', justifyContent: isMine ? 'flex-end' : 'flex-start', width: '100%' }}
    >
      <Stack
        sx={{
          maxWidth: '80%',
          px: 1.5,
          py: 1,
          borderRadius: 2,
          bgcolor: failed ? 'var(--bal-error-soft)' : isMine ? 'var(--bal-primary)' : 'var(--bal-bg-paper)',
          color: failed ? 'var(--bal-text-primary)' : isMine ? 'var(--bal-primary-contrast)' : 'var(--bal-text-primary)',
          border: failed ? '1px solid' : isMine ? 'none' : '1px solid',
          borderColor: failed ? 'var(--bal-error)' : isMine ? undefined : 'divider',
          // Mine leans to the inline-end corner, theirs to the inline-start — a subtle "tail".
          borderStartEndRadius: isMine ? 4 : undefined,
          borderStartStartRadius: isMine ? undefined : 4,
          opacity: sending ? 0.75 : 1,
        }}
      >
        {!isMine && showAuthorLabel ? (
          <Typography variant="caption" sx={{ fontWeight: 700, color: 'var(--bal-primary)', mb: 0.25 }}>
            {authorLabel}
          </Typography>
        ) : null}

        <Typography variant="body2" sx={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
          {message.body}
        </Typography>

        {failed ? (
          <Stack direction="row" sx={{ gap: 0.5, alignItems: 'center', mt: 0.5 }}>
            <Typography variant="caption" sx={{ color: 'var(--bal-error)', fontWeight: 700, flexGrow: 1 }}>
              {failedLabel}
            </Typography>
            <Button
              onClick={onRetry}
              data-testid="message-retry"
              size="small"
              sx={{ minWidth: 0, p: 0, color: 'var(--bal-error)', fontWeight: 700, textDecoration: 'underline' }}
            >
              {retryLabel}
            </Button>
            <IconButton
              size="small"
              onClick={onDiscard}
              aria-label={discardLabel}
              data-testid="message-discard"
              sx={{ color: 'var(--bal-error)' }}
            >
              <AppIcon icon="delete" size={16} color="var(--bal-error)" />
            </IconButton>
          </Stack>
        ) : (
          <Typography
            variant="caption"
            sx={{
              mt: 0.25,
              display: 'block',
              textAlign: 'end',
              opacity: isMine ? 0.8 : 1,
              color: isMine ? 'inherit' : 'var(--bal-text-secondary)',
            }}
          >
            {sending ? sendingLabel : timeLabel}
          </Typography>
        )}
      </Stack>
    </Box>
  );
};

export default MessageBubble;
