import '@testing-library/jest-dom/vitest'
import React from 'react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
import { Avatar } from './Avatar'
import { DropdownMenu } from './DropdownMenu'
import { IntegrationStatusCard } from './IntegrationStatusCard'
import { UserMenu } from './UserMenu'

afterEach(cleanup)

describe('Avatar', () => {
  it('uses name initials as fallback and exposes a default accessible label', () => {
    render(<Avatar name="홍길동" email="hong@example.com" size="sm" status="online" />)

    expect(screen.getByRole('img', { name: '홍길동' })).toHaveTextContent('홍')
    expect(screen.getByLabelText('online')).toBeInTheDocument()
  })

  it('falls back to initials when the profile image fails to load', () => {
    render(<Avatar src="https://example.com/avatar.png" name="Jane Doe" />)

    const image = screen.getByRole('img', { name: 'Jane Doe' })
    fireEvent.error(image)

    expect(screen.getByRole('img', { name: 'Jane Doe' })).toHaveTextContent('J')
  })
})

describe('DropdownMenu', () => {
  it('opens from the trigger and closes on outside click', () => {
    render(
      <div>
        <DropdownMenu trigger={<button type="button">계정</button>}>
          <DropdownMenu.Item>프로필</DropdownMenu.Item>
        </DropdownMenu>
        <button type="button">외부</button>
      </div>
    )

    fireEvent.click(screen.getByRole('button', { name: '계정' }))
    expect(screen.getByRole('menu')).toBeInTheDocument()

    fireEvent.mouseDown(screen.getByRole('button', { name: '외부' }))
    expect(screen.queryByRole('menu')).not.toBeInTheDocument()
  })

  it('skips disabled items during keyboard navigation and returns focus to trigger after selection', () => {
    const onSelect = vi.fn()
    render(
      <DropdownMenu trigger={<button type="button">액션</button>}>
        <DropdownMenu.Item disabled>비활성</DropdownMenu.Item>
        <DropdownMenu.Item onSelect={onSelect}>로그아웃</DropdownMenu.Item>
      </DropdownMenu>
    )

    const trigger = screen.getByRole('button', { name: '액션' })
    fireEvent.click(trigger)
    fireEvent.keyDown(screen.getByRole('menu'), { key: 'ArrowDown' })
    fireEvent.keyDown(screen.getByRole('menu'), { key: 'Enter' })

    expect(onSelect).toHaveBeenCalledTimes(1)
    expect(screen.queryByRole('menu')).not.toBeInTheDocument()
    expect(trigger).toHaveFocus()
  })

  it('opens from the trigger with ArrowDown and focuses the first enabled item', () => {
    render(
      <DropdownMenu trigger={<button type="button">더보기</button>}>
        <DropdownMenu.Item disabled>비활성</DropdownMenu.Item>
        <DropdownMenu.Item>첫 액션</DropdownMenu.Item>
      </DropdownMenu>
    )

    const trigger = screen.getByRole('button', { name: '더보기' })
    fireEvent.keyDown(trigger, { key: 'ArrowDown' })

    expect(screen.getByRole('menuitem', { name: '첫 액션' })).toHaveFocus()
  })
})

describe('UserMenu', () => {
  it('renders truncated user identity and calls account actions from the dropdown', () => {
    const onSettingsClick = vi.fn()
    const onLogout = vi.fn()

    render(
      <UserMenu
        user={{
          name: '홍길동',
          email: 'very.long.email.address@example-company.com',
        }}
        integrations={[{ label: 'Sheets', status: 'connected' }]}
        onSettingsClick={onSettingsClick}
        onLogout={onLogout}
      />
    )

    expect(screen.getByText('홍길동')).toBeInTheDocument()
    expect(screen.getByText('very.long.email.address@example-company.com')).toBeInTheDocument()

    fireEvent.click(screen.getByRole('button', { name: /계정 메뉴/ }))
    fireEvent.click(screen.getByRole('menuitem', { name: /계정 설정/ }))
    expect(onSettingsClick).toHaveBeenCalledTimes(1)

    fireEvent.click(screen.getByRole('button', { name: /계정 메뉴/ }))
    fireEvent.click(screen.getByRole('menuitem', { name: /로그아웃/ }))
    expect(onLogout).toHaveBeenCalledTimes(1)
  })
})

describe('IntegrationStatusCard', () => {
  it('renders status metadata and invokes configured actions', () => {
    const reconnect = vi.fn()
    const disconnect = vi.fn()

    render(
      <IntegrationStatusCard
        icon="table_chart"
        title="Google Sheets"
        status="warning"
        description="다시 연결이 필요합니다"
        metadata={<span>마지막 동기화 2분 전</span>}
        primaryAction={{ label: '다시 연결', onClick: reconnect }}
        secondaryAction={{ label: '연결 해제', onClick: disconnect, tone: 'danger' }}
      />
    )

    expect(screen.getByText('다시 연결 필요')).toBeInTheDocument()
    expect(screen.getByText('마지막 동기화 2분 전')).toBeInTheDocument()

    fireEvent.click(screen.getByRole('button', { name: '다시 연결' }))
    fireEvent.click(screen.getByRole('button', { name: '연결 해제' }))

    expect(reconnect).toHaveBeenCalledTimes(1)
    expect(disconnect).toHaveBeenCalledTimes(1)
  })
})
