import { fireEvent, render, screen } from '@testing-library/react'

import { EMAIL_LAKE_CONNECT_STORAGE_KEY, saveEmailLakeConnectIntent } from 'dbaas/utils/lake-connect'

import SignUpCallback from './SignUpCallback'

const loginMock = jest.fn()
const logoutMock = jest.fn()
const isAuthenticatedMock = jest.fn(() => false)

jest.mock('@tidbcloud/uikit', () => ({
  Alert: ({ children }: { children?: React.ReactNode }) => <div>{children}</div>,
  Box: ({ children }: { children?: React.ReactNode }) => <div>{children}</div>,
  Button: ({ children, onClick }: { children?: React.ReactNode; onClick?: React.MouseEventHandler }) => (
    <button onClick={onClick}>{children}</button>
  ),
  Flex: ({ children }: { children?: React.ReactNode }) => <div>{children}</div>,
  Typography: ({ children }: { children?: React.ReactNode }) => <div>{children}</div>
}))

jest.mock('@tidbcloud/uikit/icons', () => ({
  IconCheckCircle: () => null,
  IconXCircle: () => null
}))

jest.mock('dbaas/components/Link', () => ({
  __esModule: true,
  default: ({ children }: { children?: React.ReactNode }) => <a>{children}</a>
}))

jest.mock('dbaas/screens/User/Common/Shell', () => ({
  PageShell: ({ children }: { children?: React.ReactNode }) => <div>{children}</div>
}))

jest.mock('dbaas/screens/User/Common/FormFields', () => ({
  SigninField: () => null
}))

jest.mock('dbaas/services/auth', () => ({
  __esModule: true,
  default: {
    isAuthenticated: () => isAuthenticatedMock(),
    login: (...args: unknown[]) => loginMock(...args),
    logout: (...args: unknown[]) => logoutMock(...args)
  }
}))

jest.mock('dbaas/services/account', () => ({
  sendVerificationEmail: jest.fn()
}))

jest.mock('dbaas/services/errorCodes', () => ({
  getErrorMessage: jest.fn(() => 'error')
}))

jest.mock('dbaas/utils/tracking', () => ({
  eventTracking: jest.fn(),
  MixpanelEvents: {
    TidbCloudLake: {
      Validate: {
        RequestStarted: 'TidbCloudLake_Validate_RequestStarted'
      }
    }
  }
}))

jest.mock('dbaas/utils/useCountingDown', () => ({
  useCountingDown: () => ({ counter: 5 })
}))

describe('email signup verification Lake login', () => {
  beforeEach(() => {
    loginMock.mockReset()
    logoutMock.mockReset()
    isAuthenticatedMock.mockReset()
    isAuthenticatedMock.mockReturnValue(false)
    localStorage.clear()
    window.history.pushState({}, '', '/signup?status=success&email=person%40example.com')
  })

  test('hands union-login params to Auth0 and clears the email-only state once', () => {
    saveEmailLakeConnectIntent('?lake-connect=open&utm_source=truewatch', Date.now())

    render(<SignUpCallback />)
    const signInButton = screen.getByRole('button', { name: 'Sign In' })

    fireEvent.click(signInButton)
    fireEvent.click(signInButton)

    expect(loginMock).toHaveBeenCalledTimes(1)
    expect(loginMock).toHaveBeenCalledWith(
      '?returnTo=lake&redirectUri=https%3A%2F%2Fdev.lake.tidbcloud.com%2F%3Flake-connect%3Dopen%26utm_source%3Dtruewatch'
    )
    expect(localStorage.getItem(EMAIL_LAKE_CONNECT_STORAGE_KEY)).toBeNull()
  })

  test('logs out an existing session into the Lake sign-in flow', () => {
    isAuthenticatedMock.mockReturnValue(true)
    saveEmailLakeConnectIntent('?lake-connect=open&utm_source=truewatch', Date.now())

    render(<SignUpCallback />)
    const signInButton = screen.getByRole('button', { name: 'Sign In' })

    fireEvent.click(signInButton)
    fireEvent.click(signInButton)

    expect(logoutMock).toHaveBeenCalledTimes(1)
    expect(logoutMock).toHaveBeenCalledWith(
      '/signin?returnTo=lake&redirectUri=https%3A%2F%2Fdev.lake.tidbcloud.com%2F%3Flake-connect%3Dopen%26utm_source%3Dtruewatch',
      false
    )
    expect(loginMock).not.toHaveBeenCalled()
    expect(localStorage.getItem(EMAIL_LAKE_CONNECT_STORAGE_KEY)).toBeNull()
  })

  test('keeps the existing logout behavior for ordinary email verification', () => {
    isAuthenticatedMock.mockReturnValue(true)

    render(<SignUpCallback />)
    const signInButton = screen.getByRole('button', { name: 'Sign In' })

    fireEvent.click(signInButton)
    fireEvent.click(signInButton)

    expect(logoutMock).toHaveBeenCalledTimes(1)
    expect(logoutMock).toHaveBeenCalledWith()
    expect(loginMock).not.toHaveBeenCalled()
  })
})
