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

const { sendMock, openSettingsMock } = vi.hoisted(() => ({
  sendMock: vi.fn(),
  openSettingsMock: vi.fn(async () => ({ ok: true })),
}))

vi.mock('../../api/websocket', () => ({
  wsManager: {
    connect: vi.fn(),
    disconnect: vi.fn(),
    onMessage: vi.fn(() => () => {}),
    clearHandlers: vi.fn(),
    send: sendMock,
  },
}))

vi.mock('../../api/sessions', () => ({
  sessionsApi: {
    getMessages: vi.fn(async () => ({ messages: [] })),
    getSlashCommands: vi.fn(async () => ({ commands: [] })),
  },
}))

vi.mock('../../stores/teamStore', () => ({
  useTeamStore: {
    getState: () => ({
      getMemberBySessionId: vi.fn(() => null),
      sendMessageToMember: vi.fn(async () => {}),
      handleTeamCreated: vi.fn(),
      handleTeamUpdate: vi.fn(),
      handleTeamDeleted: vi.fn(),
    }),
  },
}))

vi.mock('../../stores/tabStore', () => ({
  useTabStore: {
    getState: () => ({
      updateTabStatus: vi.fn(),
      updateTabTitle: vi.fn(),
    }),
  },
}))

vi.mock('../../stores/sessionStore', () => ({
  useSessionStore: {
    getState: () => ({
      updateSessionTitle: vi.fn(),
    }),
  },
}))

vi.mock('../../stores/cliTaskStore', () => ({
  useCLITaskStore: {
    getState: () => ({
      fetchSessionTasks: vi.fn(),
      tasks: [],
      clearTasks: vi.fn(),
      setTasksFromTodos: vi.fn(),
      markCompletedAndDismissed: vi.fn(),
      resetCompletedTasks: vi.fn(async () => {}),
      refreshTasks: vi.fn(),
    }),
  },
}))

vi.mock('../../api/computerUse', () => ({
  computerUseApi: {
    openSettings: openSettingsMock,
  },
}))

import { useChatStore } from '../../stores/chatStore'
import { useSettingsStore } from '../../stores/settingsStore'
import { ComputerUsePermissionModal } from './ComputerUsePermissionModal'

describe('ComputerUsePermissionModal', () => {
  beforeEach(() => {
    sendMock.mockReset()
    openSettingsMock.mockReset()
    useSettingsStore.setState({ locale: 'en' })
    useChatStore.setState({ sessions: {} })
  })

  it('returns a full approval payload for resolved apps and requested flags', () => {
    render(
      <ComputerUsePermissionModal
        sessionId="session-1"
        request={{
          requestId: 'cu-1',
          reason: 'Open Finder and inspect a file',
          apps: [
            {
              requestedName: 'Finder',
              resolved: {
                bundleId: 'com.apple.finder',
                displayName: 'Finder',
              },
              isSentinel: false,
              alreadyGranted: false,
              proposedTier: 'full',
            },
            {
              requestedName: 'Missing App',
              isSentinel: false,
              alreadyGranted: false,
              proposedTier: 'full',
            },
          ],
          requestedFlags: {
            clipboardRead: true,
            systemKeyCombos: true,
          },
          screenshotFiltering: 'native',
          willHide: [{ bundleId: 'com.apple.TextEdit', displayName: 'TextEdit' }],
          autoUnhideEnabled: true,
        }}
      />,
    )

    fireEvent.click(screen.getByRole('button', { name: 'Allow for session' }))

    expect(sendMock).toHaveBeenCalledTimes(1)
    expect(sendMock).toHaveBeenCalledWith('session-1', {
      type: 'computer_use_permission_response',
      requestId: 'cu-1',
      response: {
        granted: [
          expect.objectContaining({
            bundleId: 'com.apple.finder',
            displayName: 'Finder',
            tier: 'full',
          }),
        ],
        denied: [
          {
            bundleId: 'Missing App',
            reason: 'not_installed',
          },
        ],
        flags: {
          clipboardRead: true,
          clipboardWrite: false,
          systemKeyCombos: true,
        },
        userConsented: true,
      },
    })
  })

  it('opens System Settings from the macOS permission panel', async () => {
    render(
      <ComputerUsePermissionModal
        sessionId="session-1"
        request={{
          requestId: 'cu-1',
          reason: '',
          apps: [],
          requestedFlags: {},
          screenshotFiltering: 'native',
          tccState: {
            accessibility: false,
            screenRecording: true,
          },
        }}
      />,
    )

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: 'Open Accessibility' }))
    })

    expect(openSettingsMock).toHaveBeenCalledWith('Privacy_Accessibility')
  })
})
