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

vi.mock('../api/client', () => ({
  default: {
    post: vi.fn(),
    get: vi.fn(),
    interceptors: {
      request: { use: vi.fn() },
      response: { use: vi.fn() },
    },
  },
}))

import api from '../api/client'

describe('ForgotPassword page', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  const renderPage = () => render(<MemoryRouter><ForgotPassword /></MemoryRouter>)

  it('renders form', () => {
    renderPage()
    expect(screen.getByText('Забыли пароль?')).toBeInTheDocument()
    expect(screen.getByPlaceholderText('your@email.com')).toBeInTheDocument()
    expect(screen.getByText('Отправить ссылку')).toBeInTheDocument()
  })

  it('renders back to login link', () => {
    renderPage()
    expect(screen.getByText('Вернуться ко входу')).toBeInTheDocument()
  })

  it('shows success state after submit', async () => {
    api.post.mockResolvedValueOnce({})
    renderPage()

    fireEvent.change(screen.getByPlaceholderText('your@email.com'), {
      target: { value: 'test@test.com' },
    })
    fireEvent.click(screen.getByText('Отправить ссылку'))

    await waitFor(() => {
      expect(screen.getByText('Письмо отправлено! 📬')).toBeInTheDocument()
    })
  })

  it('shows email in success state', async () => {
    api.post.mockResolvedValueOnce({})
    renderPage()

    fireEvent.change(screen.getByPlaceholderText('your@email.com'), {
      target: { value: 'myemail@test.com' },
    })
    fireEvent.click(screen.getByText('Отправить ссылку'))

    await waitFor(() => {
      expect(screen.getByText(/myemail@test\.com/)).toBeInTheDocument()
    })
  })

  it('shows error on failure', async () => {
    api.post.mockRejectedValueOnce({ response: { data: { error: 'Пользователь не найден' } } })
    renderPage()

    fireEvent.change(screen.getByPlaceholderText('your@email.com'), {
      target: { value: 'bad@test.com' },
    })
    fireEvent.click(screen.getByText('Отправить ссылку'))

    await waitFor(() => {
      expect(screen.getByText('Пользователь не найден')).toBeInTheDocument()
    })
  })

  it('shows default error message', async () => {
    api.post.mockRejectedValueOnce(new Error('Network'))
    renderPage()

    fireEvent.change(screen.getByPlaceholderText('your@email.com'), {
      target: { value: 'bad@test.com' },
    })
    fireEvent.click(screen.getByText('Отправить ссылку'))

    await waitFor(() => {
      expect(screen.getByText('Ошибка отправки')).toBeInTheDocument()
    })
  })

  it('calls correct API endpoint', async () => {
    api.post.mockResolvedValueOnce({})
    renderPage()

    fireEvent.change(screen.getByPlaceholderText('your@email.com'), {
      target: { value: 'test@test.com' },
    })
    fireEvent.click(screen.getByText('Отправить ссылку'))

    await waitFor(() => {
      expect(api.post).toHaveBeenCalledWith('/auth/forgot-password', { email: 'test@test.com' })
    })
  })
})
