// @vitest-environment happy-dom
import '@testing-library/jest-dom/vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { vi, describe, it, expect, beforeEach } from 'vitest'

const mockUseQuery = vi.hoisted(() => vi.fn())
const mockListWaitingAgentsQuery = vi.hoisted(() => vi.fn())
const mockListMessagesQuery = vi.hoisted(() => vi.fn())
const mockGetAgentQuestionsQuery = vi.hoisted(() => vi.fn())
const mockResumeAgentMutation = vi.hoisted(() => vi.fn())
const mockStopAgentMutation = vi.hoisted(() => vi.fn())
const mockRespondToMessageMutation = vi.hoisted(() => vi.fn())
const mockUseUtils = vi.hoisted(() => vi.fn())

vi.mock('@/lib/trpc', () => ({
  trpc: {
    getHeadquartersDashboard: { useQuery: mockUseQuery },
    listWaitingAgents: { useQuery: mockListWaitingAgentsQuery },
    listMessages: { useQuery: mockListMessagesQuery },
    getAgentQuestions: { useQuery: mockGetAgentQuestionsQuery },
    resumeAgent: { useMutation: mockResumeAgentMutation },
    stopAgent: { useMutation: mockStopAgentMutation },
    respondToMessage: { useMutation: mockRespondToMessageMutation },
    useUtils: mockUseUtils,
  },
}))

vi.mock('@/hooks', () => ({
  useLiveUpdates: vi.fn(),
  LiveUpdateRule: undefined,
}))

vi.mock('@/components/InboxList', () => ({
  InboxList: ({ agents, selectedAgentId, onSelectAgent }: any) => (
    <div data-testid="inbox-list">
      {agents.map((a: any) => (
        <button
          key={a.id}
          data-testid={`agent-${a.id}`}
          aria-selected={selectedAgentId === a.id}
          onClick={() => onSelectAgent(a.id)}
        >
          {a.name}
        </button>
      ))}
    </div>
  ),
}))

vi.mock('@/components/InboxDetailPanel', () => ({
  InboxDetailPanel: ({ agent, onSubmitAnswers, onDismissQuestions, onDismissMessage, onBack }: any) => (
    <div data-testid="inbox-detail">
      <span data-testid="selected-agent-name">{agent.name}</span>
      <button onClick={() => onSubmitAnswers({ q1: 'answer' })}>Submit</button>
      <button onClick={onDismissQuestions}>Dismiss Questions</button>
      <button onClick={onDismissMessage}>Dismiss Message</button>
      <button onClick={onBack}>Back</button>
    </div>
  ),
}))

vi.mock('@/components/hq/HQNeedsReviewSection', () => ({
  HQNeedsReviewSection: ({ initiatives, phases }: any) => (
    <div data-testid="needs-review">{initiatives.length},{phases.length}</div>
  ),
}))

vi.mock('@/components/hq/HQNeedsApprovalSection', () => ({
  HQNeedsApprovalSection: ({ items }: any) => <div data-testid="needs-approval">{items.length}</div>,
}))

vi.mock('@/components/hq/HQResolvingConflictsSection', () => ({
  HQResolvingConflictsSection: ({ items }: any) => <div data-testid="resolving-conflicts">{items.length}</div>,
}))

vi.mock('@/components/hq/HQBlockedSection', () => ({
  HQBlockedSection: ({ items }: any) => <div data-testid="blocked">{items.length}</div>,
}))

vi.mock('@/components/hq/HQEmptyState', () => ({
  HQEmptyState: () => <div data-testid="empty-state">All clear</div>,
}))

// Import after mocks are set up
import { HeadquartersPage } from './hq'

const emptyData = {
  waitingForInput: [],
  pendingReviewInitiatives: [],
  pendingReviewPhases: [],
  planningInitiatives: [],
  resolvingConflicts: [],
  blockedPhases: [],
}

describe('HeadquartersPage', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockListWaitingAgentsQuery.mockReturnValue({ data: [], isLoading: false })
    mockListMessagesQuery.mockReturnValue({ data: [], isLoading: false })
    mockGetAgentQuestionsQuery.mockReturnValue({ data: null, isLoading: false, isError: false })
    mockResumeAgentMutation.mockReturnValue({ mutate: vi.fn(), isPending: false, isError: false })
    mockStopAgentMutation.mockReturnValue({ mutate: vi.fn(), isPending: false, isError: false })
    mockRespondToMessageMutation.mockReturnValue({ mutate: vi.fn(), isPending: false, isError: false })
    mockUseUtils.mockReturnValue({
      listWaitingAgents: { invalidate: vi.fn() },
      listMessages: { invalidate: vi.fn() },
    })
  })

  it('renders skeleton loading state', () => {
    mockUseQuery.mockReturnValue({ isLoading: true, isError: false, data: undefined })
    render(<HeadquartersPage />)

    // Should show heading
    expect(screen.getByText('Headquarters')).toBeInTheDocument()
    // Should show skeleton elements (there are 3)
    const skeletons = document.querySelectorAll('[class*="skeleton"], [class*="h-16"]')
    expect(skeletons.length).toBeGreaterThan(0)
    // No section components
    expect(screen.queryByTestId('inbox-list')).not.toBeInTheDocument()
    expect(screen.queryByTestId('needs-review')).not.toBeInTheDocument()
    expect(screen.queryByTestId('needs-approval')).not.toBeInTheDocument()
    expect(screen.queryByTestId('blocked')).not.toBeInTheDocument()
    expect(screen.queryByTestId('empty-state')).not.toBeInTheDocument()
  })

  it('renders error state with retry button', () => {
    const mockRefetch = vi.fn()
    mockUseQuery.mockReturnValue({ isLoading: false, isError: true, data: undefined, refetch: mockRefetch })
    render(<HeadquartersPage />)

    expect(screen.getByText('Failed to load headquarters data.')).toBeInTheDocument()
    const retryButton = screen.getByRole('button', { name: /retry/i })
    expect(retryButton).toBeInTheDocument()

    fireEvent.click(retryButton)
    expect(mockRefetch).toHaveBeenCalledOnce()
  })

  it('renders empty state when all arrays are empty', () => {
    mockUseQuery.mockReturnValue({ isLoading: false, isError: false, data: emptyData })
    render(<HeadquartersPage />)

    expect(screen.getByTestId('empty-state')).toBeInTheDocument()
    expect(screen.queryByTestId('inbox-list')).not.toBeInTheDocument()
    expect(screen.queryByTestId('needs-review')).not.toBeInTheDocument()
    expect(screen.queryByTestId('needs-approval')).not.toBeInTheDocument()
    expect(screen.queryByTestId('blocked')).not.toBeInTheDocument()
  })

  it('renders InboxList when waitingForInput items exist', () => {
    mockUseQuery.mockReturnValue({
      isLoading: false,
      isError: false,
      data: { ...emptyData, waitingForInput: [{ id: '1' }] },
    })
    mockListWaitingAgentsQuery.mockReturnValue({
      data: [{ id: 'a1', name: 'Agent 1', status: 'waiting_for_input', taskId: null, updatedAt: new Date() }],
      isLoading: false,
    })
    render(<HeadquartersPage />)

    expect(screen.getByTestId('inbox-list')).toBeInTheDocument()
    expect(screen.queryByTestId('empty-state')).not.toBeInTheDocument()
  })

  it('renders all sections when all arrays have items', () => {
    mockUseQuery.mockReturnValue({
      isLoading: false,
      isError: false,
      data: {
        waitingForInput: [{ id: '1' }],
        pendingReviewInitiatives: [{ id: '2' }],
        pendingReviewPhases: [{ id: '3' }],
        planningInitiatives: [{ id: '4' }],
        resolvingConflicts: [{ id: '5' }],
        blockedPhases: [{ id: '6' }],
      },
    })
    mockListWaitingAgentsQuery.mockReturnValue({
      data: [{ id: 'a1', name: 'Agent 1', status: 'waiting_for_input', taskId: null, updatedAt: new Date() }],
      isLoading: false,
    })
    render(<HeadquartersPage />)

    expect(screen.getByTestId('inbox-list')).toBeInTheDocument()
    expect(screen.getByTestId('needs-review')).toBeInTheDocument()
    expect(screen.getByTestId('needs-approval')).toBeInTheDocument()
    expect(screen.getByTestId('resolving-conflicts')).toBeInTheDocument()
    expect(screen.getByTestId('blocked')).toBeInTheDocument()
    expect(screen.queryByTestId('empty-state')).not.toBeInTheDocument()
  })

  it('renders NeedsReview section when only pendingReviewInitiatives has items', () => {
    mockUseQuery.mockReturnValue({
      isLoading: false,
      isError: false,
      data: { ...emptyData, pendingReviewInitiatives: [{ id: '1' }] },
    })
    render(<HeadquartersPage />)

    expect(screen.getByTestId('needs-review')).toBeInTheDocument()
    expect(screen.queryByTestId('empty-state')).not.toBeInTheDocument()
  })

  it('renders NeedsReview section when only pendingReviewPhases has items', () => {
    mockUseQuery.mockReturnValue({
      isLoading: false,
      isError: false,
      data: { ...emptyData, pendingReviewPhases: [{ id: '1' }] },
    })
    render(<HeadquartersPage />)

    expect(screen.getByTestId('needs-review')).toBeInTheDocument()
    expect(screen.queryByTestId('empty-state')).not.toBeInTheDocument()
  })

  it('shows InboxDetailPanel when an agent is selected from InboxList', async () => {
    mockUseQuery.mockReturnValue({
      isLoading: false,
      isError: false,
      data: { ...emptyData, waitingForInput: [{ id: '1' }] },
    })
    mockListWaitingAgentsQuery.mockReturnValue({
      data: [{ id: 'a1', name: 'Agent 1', status: 'waiting_for_input', taskId: null, updatedAt: new Date() }],
      isLoading: false,
    })
    render(<HeadquartersPage />)

    fireEvent.click(screen.getByTestId('agent-a1'))

    expect(await screen.findByTestId('inbox-detail')).toBeInTheDocument()
    expect(screen.getByTestId('selected-agent-name')).toHaveTextContent('Agent 1')
  })

  it('clears selection when Back is clicked in InboxDetailPanel', async () => {
    mockUseQuery.mockReturnValue({
      isLoading: false,
      isError: false,
      data: { ...emptyData, waitingForInput: [{ id: '1' }] },
    })
    mockListWaitingAgentsQuery.mockReturnValue({
      data: [{ id: 'a1', name: 'Agent 1', status: 'waiting_for_input', taskId: null, updatedAt: new Date() }],
      isLoading: false,
    })
    render(<HeadquartersPage />)

    fireEvent.click(screen.getByTestId('agent-a1'))
    expect(screen.getByTestId('inbox-detail')).toBeInTheDocument()

    fireEvent.click(screen.getByRole('button', { name: /back/i }))
    expect(screen.queryByTestId('inbox-detail')).not.toBeInTheDocument()
  })
})
