import { render, screen, fireEvent } from '@testing-library/react'
import { BoardCard, toPlainSnippet } from '../BoardCard'

describe('toPlainSnippet', () => {
  it('returns empty string for nullish/empty input', () => {
    expect(toPlainSnippet(null)).toBe('')
    expect(toPlainSnippet(undefined)).toBe('')
    expect(toPlainSnippet('')).toBe('')
  })

  it('strips markdown headings, emphasis, links and code fences', () => {
    const md = '# Title\n\nSome **bold** and _italic_ with a [link](https://x.io).\n\n```js\ncode()\n```'
    const out = toPlainSnippet(md)
    expect(out).toBe('Title Some bold and italic with a link.')
    expect(out).not.toMatch(/[#*_`]|\]\(|```/)
  })

  it('strips html tags and decodes common entities', () => {
    expect(toPlainSnippet('<p>Gold &amp; silver &lt;up&gt;</p>')).toBe('Gold & silver <up>')
  })

  it('collapses whitespace to single spaces', () => {
    expect(toPlainSnippet('a\n\n  b\t c')).toBe('a b c')
  })

  it('truncates on a word boundary with an ellipsis when over the limit', () => {
    // cut(12) = "one two thre"; last boundary at 7 -> back to the whole word
    expect(toPlainSnippet('one two three four five six', 12)).toBe('one two…')
  })

  it('hard-cuts a single long token with no usable word boundary', () => {
    expect(toPlainSnippet('supercalifragilisticexpialidocious', 10)).toBe('supercalif…')
  })

  it('does not truncate when within the limit', () => {
    expect(toPlainSnippet('short', 240)).toBe('short')
  })
})

describe('BoardCard', () => {
  it('renders the title and a plain-text content snippet (markdown stripped)', () => {
    render(<BoardCard title="Gold hits record" snippet={'## Lead\n\nPrices **surged** today.'} />)
    expect(screen.getByText('Gold hits record')).toBeInTheDocument()
    expect(screen.getByText('Lead Prices surged today.')).toBeInTheDocument()
  })

  it('renders source and meta chips', () => {
    render(
      <BoardCard
        title="T"
        source="reuters.com"
        meta={[{ label: 'market', value: 'UAE' }]}
      />,
    )
    expect(screen.getByText('reuters.com')).toBeInTheDocument()
    expect(screen.getByText('market:')).toBeInTheDocument()
    expect(screen.getByText('UAE')).toBeInTheDocument()
  })

  it('calls onOpen when the title is clicked', () => {
    const onOpen = jest.fn()
    render(<BoardCard title="Open me" onOpen={onOpen} />)
    fireEvent.click(screen.getByRole('button', { name: 'Open me' }))
    expect(onOpen).toHaveBeenCalledTimes(1)
  })

  it('stops footer clicks from bubbling (so a control never starts a card drag)', () => {
    const outer = jest.fn()
    render(
      <div onClick={outer}>
        <BoardCard title="T" footer={<button type="button">status</button>} />
      </div>,
    )
    fireEvent.click(screen.getByRole('button', { name: 'status' }))
    expect(outer).not.toHaveBeenCalled()
  })
})
