import { renderHook } from '@testing-library/react-hooks'
import { useContext } from 'react'

import useStores from 'dbaas/stores/useStores'

import { useCanonicalTidbResourceContext } from '../runtime/metadata-adapter'
import { useRoleIndex } from '../runtime/role-index'

import { AccessContext } from './access-context'
import { AccessProvider } from './AccessProvider'
import { useTidbId } from './use-tidb-id'

jest.mock('dbaas/stores/useStores', () => jest.fn())
jest.mock('../runtime/metadata-adapter', () => ({
  useCanonicalTidbResourceContext: jest.fn()
}))
jest.mock('../runtime/role-index', () => ({
  useRoleIndex: jest.fn()
}))
jest.mock('./use-tidb-id', () => ({
  useTidbId: jest.fn()
}))

const mockedUseStores = useStores as jest.MockedFunction<typeof useStores>
const mockedUseCanonicalTidbResourceContext = useCanonicalTidbResourceContext as jest.MockedFunction<
  typeof useCanonicalTidbResourceContext
>
const mockedUseRoleIndex = useRoleIndex as jest.MockedFunction<typeof useRoleIndex>
const mockedUseTidbId = useTidbId as jest.MockedFunction<typeof useTidbId>

describe('AccessProvider', () => {
  afterEach(() => {
    mockedUseStores.mockReset()
    mockedUseCanonicalTidbResourceContext.mockReset()
    mockedUseRoleIndex.mockReset()
    mockedUseTidbId.mockReset()
  })

  test('injects orgId from lastVisitLocation instead of tenantData', () => {
    mockedUseStores.mockReturnValue({
      store: {
        lastVisitLocation: {
          orgId: 'org-from-last-visit',
          projectId: 'project-from-last-visit'
        },
        tenantData: {
          id: 'org-from-tenant-data'
        }
      }
    } as any)
    mockedUseTidbId.mockReturnValue('tidb-1')
    mockedUseCanonicalTidbResourceContext.mockReturnValue({
      data: {
        orgId: 'org-from-metadata',
        projectId: 'project-from-metadata',
        servicePlan: 'starter',
        tidbId: 'tidb-1'
      },
      isLoading: false,
      reason: undefined,
      source: 'cache'
    })
    mockedUseRoleIndex.mockReturnValue({
      readiness: 'pending'
    })

    const wrapper = ({ children }: React.PropsWithChildren) => <AccessProvider>{children}</AccessProvider>
    const { result } = renderHook(() => useContext(AccessContext), { wrapper })

    expect(mockedUseCanonicalTidbResourceContext).toHaveBeenCalledWith({
      enableMiniListFallback: false,
      orgId: 'org-from-last-visit',
      tidbId: 'tidb-1'
    })
    expect(result.current.orgId).toBe('org-from-last-visit')
    expect(result.current.projectId).toBe('project-from-metadata')
  })
})
