import { describe, it, expect, beforeEach, vi } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import { HelmetProvider } from 'react-helmet-async'

import { ContactSalesPage } from '../ContactSalesPage'
import { salesApi } from '@/api/sales'
import {
  __resetAppConfigCache,
  __setAppConfigCache,
} from '@/hooks/useAppConfig'

vi.mock('@/api/sales', () => ({
  salesApi: {
    createLead: vi.fn(),
  },
}))

function renderPage() {
  return render(
    <HelmetProvider>
      <MemoryRouter initialEntries={['/contact-sales']}>
        <ContactSalesPage />
      </MemoryRouter>
    </HelmetProvider>,
  )
}

function fillRequiredFields() {
  fireEvent.change(screen.getByTestId('cs-name'), { target: { value: 'Jane Doe' } })
  fireEvent.change(screen.getByTestId('cs-email'), { target: { value: 'jane@acme.com' } })
  fireEvent.change(screen.getByTestId('cs-company'), { target: { value: 'Acme MSP' } })
}

describe('ContactSalesPage', () => {
  beforeEach(() => {
    __resetAppConfigCache()
    __setAppConfigCache({
      self_serve_enabled: true,
      oauth_providers: [],
    })
    vi.clearAllMocks()
    vi.unstubAllEnvs()
  })

  it('submits form and shows confirmation', async () => {
    vi.stubEnv('VITE_CALENDLY_URL', 'https://calendly.com/resolutionflow/sales')
    vi.mocked(salesApi.createLead).mockResolvedValue({
      id: 'fake-uuid',
      status: 'received',
    })

    renderPage()

    fillRequiredFields()
    fireEvent.change(screen.getByTestId('cs-team-size'), { target: { value: '11-25' } })
    fireEvent.change(screen.getByTestId('cs-message'), {
      target: { value: 'Looking at Enterprise pricing.' },
    })

    fireEvent.click(screen.getByTestId('cs-submit'))

    await waitFor(() => {
      expect(salesApi.createLead).toHaveBeenCalledTimes(1)
    })

    const payload = vi.mocked(salesApi.createLead).mock.calls[0][0]
    expect(payload).toMatchObject({
      name: 'Jane Doe',
      email: 'jane@acme.com',
      company: 'Acme MSP',
      team_size: '11-25',
      message: 'Looking at Enterprise pricing.',
    })
    // Default source is landing_page (no /pricing in referrer in jsdom).
    expect(payload.source).toBe('landing_page')

    // Confirmation surface replaces the form.
    await waitFor(() => {
      expect(screen.getByTestId('contact-sales-confirmation')).toBeInTheDocument()
    })
    expect(screen.queryByTestId('contact-sales-form')).not.toBeInTheDocument()
    expect(screen.getByText(/Thanks/i)).toBeInTheDocument()
  })

  it('hides Calendly section when VITE_CALENDLY_URL unset', async () => {
    vi.stubEnv('VITE_CALENDLY_URL', '')
    vi.mocked(salesApi.createLead).mockResolvedValue({
      id: 'fake-uuid',
      status: 'received',
    })

    renderPage()
    fillRequiredFields()
    fireEvent.click(screen.getByTestId('cs-submit'))

    await waitFor(() => {
      expect(screen.getByTestId('contact-sales-confirmation')).toBeInTheDocument()
    })

    expect(screen.queryByTestId('calendly-block')).not.toBeInTheDocument()
    expect(screen.queryByTestId('calendly-link')).not.toBeInTheDocument()
  })

  it('disables submit button while in flight to prevent duplicate submissions', async () => {
    let resolveSubmit: (() => void) | null = null
    vi.mocked(salesApi.createLead).mockImplementation(
      () =>
        new Promise((resolve) => {
          resolveSubmit = () => resolve({ id: 'fake-uuid', status: 'received' })
        }),
    )

    renderPage()
    fillRequiredFields()

    const submit = screen.getByTestId('cs-submit') as HTMLButtonElement
    fireEvent.click(submit)

    await waitFor(() => {
      expect(submit.disabled).toBe(true)
    })

    // A second click while in flight should be a no-op.
    fireEvent.click(submit)
    expect(salesApi.createLead).toHaveBeenCalledTimes(1)

    resolveSubmit?.()
    await waitFor(() => {
      expect(screen.getByTestId('contact-sales-confirmation')).toBeInTheDocument()
    })
  })

  it('returns 404 when self_serve_enabled is false', () => {
    __resetAppConfigCache()
    __setAppConfigCache({
      self_serve_enabled: false,
      oauth_providers: [],
    })

    renderPage()

    expect(screen.getByTestId('contact-sales-not-found')).toBeInTheDocument()
    expect(screen.queryByTestId('contact-sales-form')).not.toBeInTheDocument()
  })
})
