import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

import Roles from '@/pages/Roles'

// ── Mock data ──────────────────────────────────────────────────

const mockRoles = [
  {
    id: 'role-admin', name: 'admin', description: '管理员',
    permissions: ['admin:full'], account_count: 2,
    created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z',
  },
  {
    id: 'role-user', name: 'user', description: '普通用户',
    permissions: ['model:read', 'relay:use', 'config:read', 'prompt:read'],
    account_count: 15,
    created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z',
  },
]

const mockTemplates = [
  {
    id: 'tpl-read-only', name: '只读模板', description: '仅查看权限',
    permissions: ['model:read', 'config:read'],
    created_at: '2026-02-01T00:00:00Z', updated_at: '2026-02-01T00:00:00Z',
  },
  {
    id: 'tpl-operator', name: '操作员模板', description: '操作权限',
    permissions: ['model:read', 'relay:use', 'config:read', 'prompt:read', 'hand:use'],
    created_at: '2026-02-15T00:00:00Z', updated_at: '2026-02-15T00:00:00Z',
  },
]

const server = setupServer()

beforeEach(() => {
  server.listen({ onUnhandledRequest: 'bypass' })
})

afterEach(() => {
  server.close()
})

function renderWithProviders(ui: React.ReactElement) {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  })
  return render(
    <QueryClientProvider client={queryClient}>
      {ui}
    </QueryClientProvider>,
  )
}

function setupRolesHandlers(overrides: Record<string, unknown> = {}) {
  server.use(
    http.get('*/api/v1/roles', () => {
      return HttpResponse.json(overrides.roles ?? mockRoles)
    }),
    http.get('*/api/v1/permission-templates', () => {
      return HttpResponse.json(overrides.templates ?? mockTemplates)
    }),
  )
}

describe('Roles', () => {
  it('renders page title', () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)
    expect(screen.getByText('角色与权限')).toBeInTheDocument()
  })

  it('displays tabs', () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)
    // Tabs use label spans with icons
    expect(screen.getByText('角色')).toBeInTheDocument()
    expect(screen.getByText('权限模板')).toBeInTheDocument()
  })

  it('displays roles in default tab', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    await waitFor(() => {
      expect(screen.getByText('admin')).toBeInTheDocument()
    })
    expect(screen.getByText('user')).toBeInTheDocument()
    expect(screen.getByText('管理员')).toBeInTheDocument()
    expect(screen.getByText('普通用户')).toBeInTheDocument()
  })

  it('displays permissions count tags', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    await waitFor(() => {
      // "1 项" for admin (1 permission), "4 项" for user (4 permissions)
      expect(screen.getByText('1 项')).toBeInTheDocument()
      expect(screen.getByText('4 项')).toBeInTheDocument()
    })
  })

  it('displays account count column', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    await waitFor(() => {
      expect(screen.getByText('admin')).toBeInTheDocument()
    })
    // account_count: admin=2, user=15
    expect(screen.getByText('2')).toBeInTheDocument()
    expect(screen.getByText('15')).toBeInTheDocument()
  })

  it('has 新建角色 button', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    await waitFor(() => {
      expect(screen.getByText('新建角色')).toBeInTheDocument()
    })
  })

  it('renders 操作 column for role rows', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    await waitFor(() => {
      expect(screen.getByText('admin')).toBeInTheDocument()
    })

    // 操作 column header should exist
    expect(screen.getByText('操作')).toBeInTheDocument()
  })

  it('shows empty roles state', async () => {
    setupRolesHandlers({ roles: [], templates: mockTemplates })
    renderWithProviders(<Roles />)

    await waitFor(() => {
      const empties = screen.getAllByText('暂无数据')
      expect(empties.length).toBeGreaterThanOrEqual(1)
    })
  })

  it('switches to templates tab and displays templates', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    await waitFor(() => {
      expect(screen.getByText('admin')).toBeInTheDocument()
    })

    // Click 权限模板 tab
    screen.getByText('权限模板').click()

    await waitFor(() => {
      expect(screen.getByText('只读模板')).toBeInTheDocument()
    })
    expect(screen.getByText('操作员模板')).toBeInTheDocument()
  })

  it('displays template permission counts', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    screen.getByText('权限模板').click()

    await waitFor(() => {
      // read-only: 2 permissions, operator: 5 permissions
      expect(screen.getByText('2 项')).toBeInTheDocument()
    })
  })

  it('shows empty templates state', async () => {
    setupRolesHandlers({ roles: mockRoles, templates: [] })
    renderWithProviders(<Roles />)

    await waitFor(() => {
      expect(screen.getByText('admin')).toBeInTheDocument()
    })

    screen.getByText('权限模板').click()

    await waitFor(() => {
      const empties = screen.getAllByText('暂无数据')
      expect(empties.length).toBeGreaterThanOrEqual(1)
    })
  })

  it('has 新建模板 button in templates tab', async () => {
    setupRolesHandlers()
    renderWithProviders(<Roles />)

    screen.getByText('权限模板').click()

    await waitFor(() => {
      expect(screen.getByText('新建模板')).toBeInTheDocument()
    })
  })

  it('shows empty on roles API failure', async () => {
    server.use(
      http.get('*/api/v1/roles', () => {
        return HttpResponse.json(
          { error: 'internal_error', message: '数据库错误' },
          { status: 500 },
        )
      }),
      http.get('*/api/v1/permission-templates', () => {
        return HttpResponse.json(mockTemplates)
      }),
    )
    renderWithProviders(<Roles />)

    await waitFor(() => {
      // ProTable shows 暂无数据 when data fetch fails
      const empties = screen.getAllByText('暂无数据')
      expect(empties.length).toBeGreaterThanOrEqual(1)
    })
  })
})
