/**
 * Smoke tests for the shared TeamSettingsPage composer (startsim-o7s).
 *
 * The real auth hooks are mocked so the test doesn't spin up an AuthProvider
 * — we just confirm the page wires the supplied api shape through to the
 * presentational components (MembersTable, invitations table, danger zone).
 */
import { render, screen, waitFor, fireEvent, act } from '@testing-library/react'
import { TeamSettingsPage } from '../pages/TeamSettingsPage'
import { DomainsSettingsPage } from '../pages/DomainsSettingsPage'

jest.mock('@startsimpli/auth', () => {
  const noop = () => {}
  return {
    __esModule: true,
    useAuth: () => ({
      user: { id: 'u1', email: 'q@x.com' },
      logout: jest.fn().mockResolvedValue(undefined),
    }),
    buildCentralAuthUrl: (flow: string, opts: { app: string }) =>
      `https://auth.startsimpli.com/${flow}?app=${opts.app}`,
    useMembershipFromApi: () => ({
      company: { id: 'c1', slug: 'acme', name: 'Acme' },
      currentTeam: { id: 't1', slug: 'core', name: 'Core', companyId: 'c1' },
      role: 'owner',
      isOwner: true,
      isAdmin: true,
      isMemberOrAbove: true,
      canInvite: true,
      memberships: [],
      isLoading: false,
      error: null,
      refresh: jest.fn().mockResolvedValue(undefined),
    }),
    useInvitations: ({ fetchInvitations, autoFetch: _ }: { fetchInvitations: () => Promise<unknown>; autoFetch?: boolean }) => ({
      pending: [],
      isLoading: false,
      error: null,
      refresh: async () => {
        await fetchInvitations()
      },
      revoke: noop,
      bulkInvite: async () => ({ invited: [] }),
    }),
    useDomainClaims: () => ({
      claims: [],
      isLoading: false,
      error: null,
      refresh: jest.fn().mockResolvedValue(undefined),
      create: jest.fn(),
      verifyDns: jest.fn(),
      initiateEmail: jest.fn(),
      verifyEmail: jest.fn(),
      revoke: jest.fn(),
    }),
  }
})

function buildApi() {
  return {
    teams: {
      myTeams: jest.fn().mockResolvedValue([]),
      retrieve: jest.fn(),
      members: jest.fn().mockResolvedValue([
        {
          id: 'm1',
          userId: 'u1',
          teamId: 't1',
          role: 'owner',
          joinedAt: '2025-01-01',
          user: { id: 'u1', email: 'q@x.com', firstName: 'Quinn' },
        },
      ]),
      updateRole: jest.fn().mockResolvedValue(undefined),
      removeMember: jest.fn().mockResolvedValue(undefined),
      bulkInvite: jest.fn().mockResolvedValue({ invited: [], skipped: [] }),
    },
    teamInvitations: {
      list: jest.fn().mockResolvedValue({ results: [] }),
      create: jest.fn(),
      revoke: jest.fn().mockResolvedValue(undefined),
    },
    companies: {
      retrieve: jest.fn(),
    },
    domainClaims: {
      list: jest.fn().mockResolvedValue({ results: [] }),
      create: jest.fn(),
      verifyDns: jest.fn(),
      verifyEmailInitiate: jest.fn(),
      verifyEmailCode: jest.fn(),
      revoke: jest.fn(),
    },
  } as any
}

describe('TeamSettingsPage', () => {
  it('renders header + members table after fetch', async () => {
    const api = buildApi()
    render(<TeamSettingsPage api={api} centralAuthApp="vault" />)
    expect(screen.getByText('Team & members')).toBeInTheDocument()
    expect(screen.getByText('Acme · Core')).toBeInTheDocument()
    await waitFor(() => {
      expect(api.teams.members).toHaveBeenCalledWith('core')
    })
    expect(screen.getByText(/Quinn/)).toBeInTheDocument()
  })

  it('shows the danger-zone Leave button for the current team', async () => {
    const api = buildApi()
    render(<TeamSettingsPage api={api} centralAuthApp="vault" />)
    await waitFor(() => expect(api.teams.members).toHaveBeenCalled())
    expect(screen.getByText('Danger zone')).toBeInTheDocument()
    expect(screen.getByRole('button', { name: /Leave team/i })).toBeInTheDocument()
  })

  it('exposes the +Invite trigger when the current user is admin', async () => {
    const api = buildApi()
    render(<TeamSettingsPage api={api} centralAuthApp="vault" />)
    await waitFor(() => expect(api.teams.members).toHaveBeenCalled())
    expect(screen.getByRole('button', { name: '+ Invite' })).toBeInTheDocument()
  })
})

describe('DomainsSettingsPage', () => {
  it('renders the title + Add Domain trigger when admin + has companyId', async () => {
    const api = buildApi()
    render(<DomainsSettingsPage api={api} />)
    expect(screen.getByText('Email domains')).toBeInTheDocument()
    expect(screen.getByRole('button', { name: /Add domain/i })).toBeInTheDocument()
  })

  it('opens the add-domain form when clicked + validates input', async () => {
    const api = buildApi()
    render(<DomainsSettingsPage api={api} />)
    act(() => {
      fireEvent.click(screen.getByRole('button', { name: /Add domain/i }))
    })
    const input = screen.getByLabelText(/Domain/i) as HTMLInputElement
    fireEvent.change(input, { target: { value: 'nope' } })
    fireEvent.click(screen.getByRole('button', { name: /Add domain/i }))
    expect(
      await screen.findByText(/valid domain/i),
    ).toBeInTheDocument()
  })
})
