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

/**
 * Render tests for the rebuilt Users tab: dynamic metric cards, access-review
 * banner, team table (members + pending invites), role filter pills, search,
 * and the invite modal.
 */

const MEMBERS = [
  {
    id: 'u1',
    name: 'Dana Chen',
    email: 'dana@actuatemedia.com',
    initials: 'DC',
    role: 'OWNER',
    roleName: 'Owner',
    status: 'active',
    mfaEnabled: true,
    externalDomain: false,
    lastLoginAt: new Date().toISOString(),
    lastActiveAt: new Date().toISOString(),
    acceptedInviteAt: new Date().toISOString(),
    createdAt: new Date().toISOString(),
    isCurrentUser: true,
  },
  {
    id: 'u2',
    name: 'Priya Nair',
    email: 'priya@actuatemedia.com',
    initials: 'PN',
    role: 'EDITOR',
    roleName: 'Editor',
    status: 'active',
    mfaEnabled: true,
    externalDomain: false,
    lastLoginAt: new Date(Date.now() - 86400000).toISOString(),
    lastActiveAt: new Date(Date.now() - 86400000).toISOString(),
    acceptedInviteAt: new Date().toISOString(),
    createdAt: new Date().toISOString(),
    isCurrentUser: false,
  },
]

const INVITES = [
  {
    id: 'i1',
    email: 'jordan@actuatemedia.com',
    role: 'EDITOR',
    roleName: 'Editor',
    status: 'PENDING',
    expiresAt: new Date(Date.now() + 5 * 86400000).toISOString(),
    createdAt: new Date(Date.now() - 2 * 86400000).toISOString(),
    expired: false,
  },
]

const STATS = {
  members: 2,
  pendingInvites: 1,
  admins: 1,
  seatsUsed: 3,
  seatLimit: 10,
  seatsAvailable: 7,
  emailConfigured: true,
}

const REVIEW = [
  {
    id: 'inactive_user:u9',
    userId: 'u9',
    severity: 'high',
    type: 'inactive_user',
    title: 'Access review',
    description: "Sara Lindqvist (sara@freelance.io) hasn't signed in for 94 days.",
    recommendedAction: 'Revoke access',
  },
]

const { cmsApi } = vi.hoisted(() => ({ cmsApi: vi.fn() }))

vi.mock('../../lib/api.js', () => ({ cmsApi }))

cmsApi.mockImplementation(async (endpoint?: string) => {
  if (!endpoint) return { data: null }
  if (endpoint.startsWith('/users/stats')) return { data: STATS }
  if (endpoint.startsWith('/users')) return { data: MEMBERS }
  if (endpoint.startsWith('/invites')) return { data: INVITES }
  if (endpoint.startsWith('/access-review')) return { data: REVIEW }
  return { data: null }
})

const { Users } = await import('../../views/Users.js')

describe('Users tab', () => {
  beforeEach(() => cmsApi.mockClear())

  it('renders dynamic metric cards', async () => {
    render(<Users embedded />)
    expect(await screen.findByText('Members')).toBeTruthy()
    expect(screen.getByText('Pending invites')).toBeTruthy()
    expect(screen.getByText('Admins')).toBeTruthy()
    expect(screen.getByText('Seats used')).toBeTruthy()
    expect(screen.getByText('3 / 10')).toBeTruthy()
  })

  it('renders the access review banner with the AI badge', async () => {
    render(<Users embedded />)
    expect(await screen.findByText('Access review')).toBeTruthy()
    expect(screen.getByText('AI')).toBeTruthy()
    expect(screen.getByText(/hasn't signed in for 94 days/)).toBeTruthy()
  })

  it('renders members and pending invites in the team table', async () => {
    render(<Users embedded />)
    expect(await screen.findByText('Dana Chen')).toBeTruthy()
    expect(screen.getByText('Priya Nair')).toBeTruthy()
    // pending invite row
    expect(screen.getByText('jordan@actuatemedia.com')).toBeTruthy()
    expect(screen.getByText('Invited')).toBeTruthy()
    expect(screen.getByText(/people have access/)).toBeTruthy()
  })

  it('filters by role pill', async () => {
    render(<Users embedded />)
    await screen.findByText('Dana Chen')
    fireEvent.click(screen.getByRole('button', { name: 'Owner', pressed: false }))
    await waitFor(() => expect(screen.queryByText('Priya Nair')).toBeNull())
    expect(screen.getByText('Dana Chen')).toBeTruthy()
  })

  it('filters by search', async () => {
    render(<Users embedded />)
    await screen.findByText('Dana Chen')
    fireEvent.change(screen.getByLabelText('Search team members'), { target: { value: 'priya' } })
    await waitFor(() => expect(screen.queryByText('Dana Chen')).toBeNull())
    expect(screen.getByText('Priya Nair')).toBeTruthy()
  })

  it('opens the invite modal with role radio cards', async () => {
    render(<Users embedded />)
    await screen.findByText('Dana Chen')
    fireEvent.click(screen.getByRole('button', { name: /Invite user/ }))
    const dialog = await screen.findByRole('dialog')
    expect(within(dialog).getByText('Invite a user')).toBeTruthy()
    expect(within(dialog).getByPlaceholderText('name@company.com')).toBeTruthy()
    // Owner sees the advanced Owner role card too (current user is Owner).
    expect(within(dialog).getByText('Owner')).toBeTruthy()
    expect(within(dialog).getByText('Admin')).toBeTruthy()
    expect(within(dialog).getByText('Editor')).toBeTruthy()
    expect(within(dialog).getByText('Viewer')).toBeTruthy()
    expect(within(dialog).getByRole('button', { name: 'Send invite' })).toBeTruthy()
  })
})
