import { describe, it, expect, vi } from 'vitest'

import { renderWithProviders, screen } from '../../../test/utils'

import MediaCard from './components/Media/Card'
import TextCard from './components/Text/Card'

/**
 * Characterization tests — the safety net for the LockedAttachment
 * separate-concerns refactor. They assert stable, user-visible facts only
 * (lock affordances, CTAs, amount/status text, the preview toggle), never
 * DOM structure or class names — exactly the things the refactor moves
 * around. Storybook remains the pixel-level visual oracle.
 */
describe('LockedAttachment (characterization)', () => {
  describe('Draft', () => {
    it('media mode: shows the placeholder title when locked with no title', () => {
      renderWithProviders(<MediaCard isDraft />)
      expect(screen.getByText('Attachment title')).toBeInTheDocument()
    })

    it('media mode: renders a preview toggle when a source fetcher is wired', () => {
      renderWithProviders(
        <MediaCard
          isDraft
          onFetchSource={vi.fn().mockResolvedValue(undefined)}
        />
      )
      expect(
        screen.getByRole('button', { name: 'Toggle preview' })
      ).toBeInTheDocument()
    })

    it('media mode: renders a dismiss control when onDismiss is provided', () => {
      renderWithProviders(<MediaCard isDraft onDismiss={vi.fn()} />)
      expect(
        screen.getByRole('button', { name: 'Dismiss attachment' })
      ).toBeInTheDocument()
    })

    it('text mode: shows the draft text and amount', () => {
      renderWithProviders(
        <TextCard isDraft amountText="$5" renderedText="Secret draft" />
      )
      expect(screen.getByText('Secret draft')).toBeInTheDocument()
      expect(screen.getByText('$5')).toBeInTheDocument()
    })
  })

  describe('Preview', () => {
    it('media mode: shows the placeholder title when locked with no title', () => {
      renderWithProviders(<MediaCard isPreview amountText="$5" />)
      expect(screen.getByText('Attachment title')).toBeInTheDocument()
      expect(screen.getByText('$5')).toBeInTheDocument()
    })

    it('text mode: never shows real text, only the amount', () => {
      renderWithProviders(<TextCard isPreview amountText="$5" />)
      expect(screen.queryByText('Secret draft')).not.toBeInTheDocument()
      expect(screen.getByText('$5')).toBeInTheDocument()
    })
  })

  describe('Media (isMine)', () => {
    it('shows the amount in the status badge', () => {
      renderWithProviders(<MediaCard isMine amountText="$5" />)
      expect(screen.getByText('$5')).toBeInTheDocument()
    })
  })

  describe('Text (isMine)', () => {
    it('pending: shows the amount with no status label', () => {
      renderWithProviders(
        <TextCard isMine amountText="$5" paymentStatus="pending" />
      )
      expect(screen.queryByText('Sent')).not.toBeInTheDocument()
      expect(screen.getByText('$5')).toBeInTheDocument()
    })

    it('paid: shows the Sold label', () => {
      renderWithProviders(
        <TextCard isMine amountText="$5" paymentStatus="paid" />
      )
      expect(screen.getByText('Sold')).toBeInTheDocument()
    })
  })

  describe('Media (!isMine)', () => {
    it('renders the locked-attachment root and an Unlock CTA when locked', () => {
      renderWithProviders(
        <MediaCard isMine={false} amountText="$5" onUnlockClick={vi.fn()} />
      )
      expect(screen.getByTestId('locked-attachment')).toBeInTheDocument()
      expect(screen.getByRole('button', { name: 'Unlock' })).toBeInTheDocument()
    })
  })

  describe('Text (!isMine)', () => {
    it('shows an Unlock control and the amount', () => {
      renderWithProviders(
        <TextCard isMine={false} amountText="$5" onUnlockClick={vi.fn()} />
      )
      expect(
        screen.getByRole('button', { name: 'Unlock message' })
      ).toBeInTheDocument()
      expect(screen.getByText('$5')).toBeInTheDocument()
    })

    it('unlocking: marks the Unlock control busy', () => {
      renderWithProviders(
        <TextCard isMine={false} isUnlocking onUnlockClick={vi.fn()} />
      )
      const button = screen.getByRole('button', { name: 'Unlocking message' })
      expect(button).toBeDisabled()
      expect(button).toHaveAttribute('aria-busy', 'true')
    })
  })
})
