/*
 * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file)
 *
 * SPDX-License-Identifier: AGPL-3.0-only
 */
import * as AliasModule from '../../../../../../api/alias'
import * as NoteDetailsReduxModule from '../../../../../../redux/note-details/methods'
import type { NoteDetails } from '../../../../../../redux/note-details/types'
import { mockI18n } from '../../../../../../test-utils/mock-i18n'
import { mockNotePermissions } from '../../../../../../test-utils/mock-note-permissions'
import { AliasesAddForm } from './aliases-add-form'
import { act, render, type RenderResult, screen } from '@testing-library/react'
import testEvent from '@testing-library/user-event'
import React from 'react'
import { mockUiNotifications } from '../../../../../../test-utils/mock-ui-notifications'

jest.mock('../../../../../../api/alias')
jest.mock('../../../../../../redux/note-details/methods')
jest.mock('../../../../../../hooks/common/use-application-state')
jest.mock('../../../../../notifications/ui-notification-boundary')

describe('AliasesAddForm', () => {
  let view: RenderResult
  let input: HTMLElement
  let button: HTMLElement
  beforeEach(async () => {
    await mockI18n()
    mockUiNotifications()
    jest.spyOn(AliasModule, 'addAlias').mockImplementation(() => Promise.resolve())
    jest.spyOn(NoteDetailsReduxModule, 'updateMetadata').mockImplementation(() => Promise.resolve())
    mockNotePermissions('test', 'test', undefined, {
      noteDetails: { primaryAlias: 'mock-alias-primary' } as NoteDetails
    })
    view = render(<AliasesAddForm />)
    input = await screen.findByTestId('addAliasInput')
    button = await screen.findByTestId('addAliasButton')
  })

  afterAll(() => {
    jest.resetAllMocks()
    jest.resetModules()
  })

  it('renders the input form', async () => {
    expect(view.container).toMatchSnapshot()
  })
  it('valid alias does not show error and enables submit button', async () => {
    expect(button).toBeDisabled()
    await testEvent.type(input, 'mock-alias-new')
    expect(input).not.toHaveClass('is-invalid')
    expect(button).toBeEnabled()
    await act<void>(() => {
      button.click()
    })
    expect(AliasModule.addAlias).toHaveBeenCalledWith('mock-alias-primary', 'mock-alias-new')
    expect(NoteDetailsReduxModule.updateMetadata).toBeCalled()
  })

  it('invalid alias shows error and disables submit button', async () => {
    input = await screen.findByTestId('addAliasInput')
    await testEvent.type(input, ' ')
    expect(input).toHaveClass('is-invalid')
    button = await screen.findByTestId('addAliasButton')
    expect(button).toBeDisabled()
  })
})
