import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent, waitFor, within } from '@testing-library/react'
import { I18nProvider } from '../i18n'
import { D2OperatorPage } from './D2OperatorPage'
import * as api from '../api/identity'

vi.mock('../api/identity')

const operatorAccount = {
  id: 'op1', public_handle: 'op', display_alias: 'Op', role: 'operator',
  status: 'active', preferred_language: 'en',
}

const renderPage = (onNav = () => {}) =>
  render(<I18nProvider initial="en"><D2OperatorPage onNav={onNav} /></I18nProvider>)

function asOperator() {
  vi.mocked(api.getD2Account).mockReturnValue(operatorAccount)
  vi.mocked(api.getD2Csrf).mockReturnValue('csrf')
  vi.mocked(api.onD2Change).mockReturnValue(() => {})
  vi.mocked(api.listInvitations).mockResolvedValue([])
  vi.mocked(api.listOperatorAccounts).mockResolvedValue([])
}

describe('D2OperatorPage', () => {
  beforeEach(() => vi.resetAllMocks())

  it('blocks non-operators', () => {
    vi.mocked(api.getD2Account).mockReturnValue({ ...operatorAccount, role: 'customer' })
    vi.mocked(api.onD2Change).mockReturnValue(() => {})
    renderPage()
    expect(screen.getByText('This area is for operators only.')).toBeInTheDocument()
  })

  it('creates invitations and warns the codes are shown once', async () => {
    asOperator()
    vi.mocked(api.createInvitations).mockResolvedValue([{ id: 'i1', code: 'ABCD-1234' }])
    renderPage()
    fireEvent.click(await screen.findByRole('button', { name: 'Create' }))
    expect(await screen.findByText('ABCD-1234')).toBeInTheDocument()
    expect(screen.getByText(/shown only once/)).toBeInTheDocument()
  })

  it('confirms a destructive account action', async () => {
    asOperator()
    vi.mocked(api.listOperatorAccounts).mockResolvedValue([{
      id: 'a1', public_handle: 'ali', display_alias: 'Ali', role: 'customer', status: 'active',
      preferred_language: 'en', passkey_count: 2, active_session_count: 1, created_at: '2026-01-01',
    }])
    vi.mocked(api.getOperatorAccount).mockResolvedValue({
      account: {
        id: 'a1', public_handle: 'ali', display_alias: 'Ali', role: 'customer', status: 'active',
        preferred_language: 'en', passkey_count: 2, active_session_count: 1, created_at: '2026-01-01',
      },
      events: [],
    })
    vi.mocked(api.operatorDeleteAccount).mockResolvedValue()
    renderPage()
    fireEvent.click(screen.getByRole('tab', { name: 'Accounts' }))
    fireEvent.click(await screen.findByRole('button', { name: 'View' }))
    fireEvent.click(await screen.findByRole('button', { name: 'Delete' }))
    const dialog = await screen.findByRole('alertdialog')
    fireEvent.click(within(dialog).getByRole('button', { name: 'Delete' }))
    await waitFor(() => expect(api.operatorDeleteAccount).toHaveBeenCalledWith('a1'))
  })
})
