import { render, screen, fireEvent } from '@testing-library/react';
import { ThemeProvider } from '../../theme';
import MessageBubble from './MessageBubble';
import type { TicketMessage } from '@/services/tickets/types';

const base: TicketMessage = {
  id: 1,
  ticketId: 10,
  body: 'سلام، ساعت ویزیت را تغییر دهید',
  authorRole: 'admin',
  createdAt: '2026-07-01T10:00:00Z',
  isMine: false,
  sendStatus: 'sent',
};

function renderBubble(overrides: Partial<TicketMessage>, extra: { showAuthorLabel?: boolean; onRetry?: () => void; onDiscard?: () => void } = {}) {
  return render(
    <ThemeProvider>
      <MessageBubble
        message={{ ...base, ...overrides }}
        authorLabel="پشتیبانی"
        showAuthorLabel={extra.showAuthorLabel ?? true}
        timeLabel="۱۰:۰۰"
        sendingLabel="در حال ارسال…"
        failedLabel="پیام ارسال نشد"
        retryLabel="تلاش مجدد"
        discardLabel="حذف"
        onRetry={extra.onRetry}
        onDiscard={extra.onDiscard}
      />
    </ThemeProvider>,
  );
}

describe('<MessageBubble/> component', () => {
  it("aligns others' messages to the start and shows the author label + time", () => {
    renderBubble({ isMine: false });
    expect(screen.getByTestId('message-bubble')).toHaveAttribute('data-mine', 'false');
    expect(screen.getByText('پشتیبانی')).toBeInTheDocument();
    expect(screen.getByText('سلام، ساعت ویزیت را تغییر دهید')).toBeInTheDocument();
    expect(screen.getByText('۱۰:۰۰')).toBeInTheDocument();
  });

  it('hides the author label when it is not the head of its group', () => {
    renderBubble({ isMine: false }, { showAuthorLabel: false });
    expect(screen.queryByText('پشتیبانی')).not.toBeInTheDocument();
  });

  it('marks my messages as mine and never shows an author label', () => {
    renderBubble({ isMine: true });
    expect(screen.getByTestId('message-bubble')).toHaveAttribute('data-mine', 'true');
    expect(screen.queryByText('پشتیبانی')).not.toBeInTheDocument();
  });

  it('shows the sending label (not the time) while a message is pending', () => {
    renderBubble({ isMine: true, id: null, clientMessageId: 'c1', sendStatus: 'sending' });
    expect(screen.getByText('در حال ارسال…')).toBeInTheDocument();
    expect(screen.queryByText('۱۰:۰۰')).not.toBeInTheDocument();
  });

  it('announces a failed send (role="alert") and offers retry + discard in place', () => {
    const onRetry = jest.fn();
    const onDiscard = jest.fn();
    renderBubble(
      { isMine: true, id: null, clientMessageId: 'c1', sendStatus: 'failed' },
      { onRetry, onDiscard },
    );
    const bubble = screen.getByTestId('message-bubble');
    expect(bubble).toHaveAttribute('role', 'alert');
    expect(screen.getByText('سلام، ساعت ویزیت را تغییر دهید')).toBeInTheDocument();
    fireEvent.click(screen.getByTestId('message-retry'));
    expect(onRetry).toHaveBeenCalledTimes(1);
    fireEvent.click(screen.getByTestId('message-discard'));
    expect(onDiscard).toHaveBeenCalledTimes(1);
  });
});
