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

// Simple icon stub usable as React.ElementType
const TestIcon = () => <svg data-testid="test-icon" />

// ---------------------------------------------------------------------------
// IntegrationCard
// ---------------------------------------------------------------------------

describe('IntegrationCard', () => {
  const baseProps = {
    name: 'Salesforce',
    description: 'Sync leads and deals from Salesforce CRM.',
    icon: TestIcon,
    status: 'available' as const,
  }

  it('renders name and description', () => {
    render(<IntegrationCard {...baseProps} />)
    expect(screen.getByText('Salesforce')).toBeInTheDocument()
    expect(screen.getByText('Sync leads and deals from Salesforce CRM.')).toBeInTheDocument()
  })

  it('shows "Available" badge for available status', () => {
    render(<IntegrationCard {...baseProps} />)
    expect(screen.getByText('Available')).toBeInTheDocument()
  })

  it('shows "Connected" badge for connected status', () => {
    render(<IntegrationCard {...baseProps} status="connected" />)
    expect(screen.getByText('Connected')).toBeInTheDocument()
  })

  it('shows "Coming Soon" badge for coming-soon status', () => {
    render(<IntegrationCard {...baseProps} status="coming-soon" />)
    expect(screen.getByText('Coming Soon')).toBeInTheDocument()
  })

  it('renders icon', () => {
    render(<IntegrationCard {...baseProps} />)
    expect(screen.getByTestId('test-icon')).toBeInTheDocument()
  })

  it('shows Configure link for clickable statuses', () => {
    render(<IntegrationCard {...baseProps} onClick={jest.fn()} />)
    expect(screen.getByText('Configure')).toBeInTheDocument()
  })

  it('does not show Configure link for coming-soon status', () => {
    render(<IntegrationCard {...baseProps} status="coming-soon" />)
    expect(screen.queryByText('Configure')).not.toBeInTheDocument()
  })

  it('calls onClick when clicked for available status', () => {
    const onClick = jest.fn()
    render(<IntegrationCard {...baseProps} onClick={onClick} />)
    fireEvent.click(screen.getByRole('button'))
    expect(onClick).toHaveBeenCalledTimes(1)
  })

  it('calls onClick on Enter key press for clickable cards', () => {
    const onClick = jest.fn()
    render(<IntegrationCard {...baseProps} onClick={onClick} />)
    fireEvent.keyDown(screen.getByRole('button'), { key: 'Enter' })
    expect(onClick).toHaveBeenCalledTimes(1)
  })

  it('calls onClick on Space key press for clickable cards', () => {
    const onClick = jest.fn()
    render(<IntegrationCard {...baseProps} onClick={onClick} />)
    fireEvent.keyDown(screen.getByRole('button'), { key: ' ' })
    expect(onClick).toHaveBeenCalledTimes(1)
  })

  it('does not have role=button for coming-soon', () => {
    render(<IntegrationCard {...baseProps} status="coming-soon" />)
    expect(screen.queryByRole('button')).not.toBeInTheDocument()
  })

  it('shows lastSync when provided', () => {
    render(<IntegrationCard {...baseProps} status="connected" lastSync="2 hours ago" />)
    expect(screen.getByText('Last synced: 2 hours ago')).toBeInTheDocument()
  })

  it('does not show lastSync when not provided', () => {
    render(<IntegrationCard {...baseProps} />)
    expect(screen.queryByText(/last synced/i)).not.toBeInTheDocument()
  })

  it('applies custom className', () => {
    const { container } = render(
      <IntegrationCard {...baseProps} className="my-class" />
    )
    expect(container.firstChild).toHaveClass('my-class')
  })

  it('applies opacity for coming-soon status', () => {
    const { container } = render(
      <IntegrationCard {...baseProps} status="coming-soon" />
    )
    expect(container.firstChild).toHaveClass('opacity-75')
  })
})

// ---------------------------------------------------------------------------
// ConnectionStatus
// ---------------------------------------------------------------------------

describe('ConnectionStatus', () => {
  const baseProps = {
    providerName: 'Gmail',
    providerIcon: TestIcon,
    connected: false,
  }

  it('renders provider name', () => {
    render(<ConnectionStatus {...baseProps} />)
    expect(screen.getByText('Gmail')).toBeInTheDocument()
  })

  it('renders provider icon', () => {
    render(<ConnectionStatus {...baseProps} />)
    expect(screen.getByTestId('test-icon')).toBeInTheDocument()
  })

  it('shows "Not connected" when connected is false', () => {
    render(<ConnectionStatus {...baseProps} />)
    expect(screen.getByText('Not connected')).toBeInTheDocument()
  })

  it('shows Connect button when not connected', () => {
    render(<ConnectionStatus {...baseProps} onConnect={jest.fn()} />)
    expect(screen.getByRole('button', { name: /connect/i })).toBeInTheDocument()
  })

  it('shows Disconnect button when connected', () => {
    render(<ConnectionStatus {...baseProps} connected onDisconnect={jest.fn()} />)
    expect(screen.getByRole('button', { name: /disconnect/i })).toBeInTheDocument()
  })

  it('shows accountLabel when connected', () => {
    render(
      <ConnectionStatus
        {...baseProps}
        connected
        accountLabel="jane@example.com"
      />
    )
    expect(screen.getByText('jane@example.com')).toBeInTheDocument()
  })

  it('does not show accountLabel when not connected', () => {
    render(
      <ConnectionStatus
        {...baseProps}
        connected={false}
        accountLabel="jane@example.com"
      />
    )
    expect(screen.queryByText('jane@example.com')).not.toBeInTheDocument()
  })

  it('calls onConnect when Connect is clicked', () => {
    const onConnect = jest.fn()
    render(<ConnectionStatus {...baseProps} onConnect={onConnect} />)
    fireEvent.click(screen.getByRole('button', { name: /connect/i }))
    expect(onConnect).toHaveBeenCalledTimes(1)
  })

  it('calls onDisconnect when Disconnect is clicked', () => {
    const onDisconnect = jest.fn()
    render(<ConnectionStatus {...baseProps} connected onDisconnect={onDisconnect} />)
    fireEvent.click(screen.getByRole('button', { name: /disconnect/i }))
    expect(onDisconnect).toHaveBeenCalledTimes(1)
  })

  it('shows loading state when isLoading is true', () => {
    render(<ConnectionStatus {...baseProps} isLoading />)
    expect(screen.getByText('Loading...')).toBeInTheDocument()
    expect(screen.getByText('Loading...').closest('button')).toBeDisabled()
  })

  it('applies custom className', () => {
    const { container } = render(
      <ConnectionStatus {...baseProps} className="my-class" />
    )
    expect(container.firstChild).toHaveClass('my-class')
  })
})
