import { describe, it, expect, vi } from "vitest"
import { render, screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { Contact } from "./contact"

describe("Contact", () => {
  it("renders trigger button with label", () => {
    render(<Contact onSubmit={vi.fn()} />)
    expect(screen.getByRole("button", { name: /contact us/i })).toBeInTheDocument()
  })

  it("opens popover on click", async () => {
    const user = userEvent.setup()
    render(<Contact onSubmit={vi.fn()} />)

    await user.click(screen.getByRole("button"))

    expect(screen.getByLabelText("Name")).toBeInTheDocument()
  })

  it("opens modal when variant is modal", async () => {
    const user = userEvent.setup()
    render(<Contact variant="modal" onSubmit={vi.fn()} />)

    await user.click(screen.getByRole("button"))

    expect(screen.getByRole("dialog")).toBeInTheDocument()
  })

  it("shows all fields by default", async () => {
    const user = userEvent.setup()
    render(<Contact variant="modal" onSubmit={vi.fn()} />)

    await user.click(screen.getByRole("button"))

    expect(screen.getByLabelText("Name")).toBeInTheDocument()
    expect(screen.getByLabelText("Email")).toBeInTheDocument()
    expect(screen.getByRole("combobox")).toBeInTheDocument() // Topic dropdown
    expect(screen.getByLabelText("Message")).toBeInTheDocument()
  })

  it("hides fields when props are false", async () => {
    const user = userEvent.setup()
    render(
      <Contact
        showName={false}
        showEmail={false}
        showTopic={false}
        onSubmit={vi.fn()}
      />
    )

    await user.click(screen.getByRole("button"))

    expect(screen.queryByLabelText("Name")).not.toBeInTheDocument()
    expect(screen.queryByLabelText("Email")).not.toBeInTheDocument()
    expect(screen.queryByLabelText("Topic")).not.toBeInTheDocument()
    expect(screen.getByLabelText("Message")).toBeInTheDocument()
  })

  it("disables submit until required fields are valid", async () => {
    const user = userEvent.setup()
    render(<Contact onSubmit={vi.fn()} />)

    await user.click(screen.getByRole("button"))

    const submitButton = screen.getByRole("button", { name: "Send" })
    expect(submitButton).toBeDisabled()
  })

  it("pre-fills fields from user prop", async () => {
    const user = userEvent.setup()
    render(
      <Contact
        user={{ name: "Jane Doe", email: "jane@example.com" }}
        onSubmit={vi.fn()}
      />
    )

    await user.click(screen.getByRole("button"))

    expect(screen.getByLabelText("Name")).toHaveValue("Jane Doe")
    expect(screen.getByLabelText("Email")).toHaveValue("jane@example.com")
  })

  it("calls onSubmit with form data", async () => {
    const user = userEvent.setup()
    const handleSubmit = vi.fn()
    render(
      <Contact
        showTopic={false}
        captureMetadata={false}
        onSubmit={handleSubmit}
      />
    )

    await user.click(screen.getByRole("button"))
    await user.type(screen.getByLabelText("Name"), "John Doe")
    await user.type(screen.getByLabelText("Email"), "john@example.com")
    await user.type(screen.getByLabelText("Message"), "This is a test message for support.")
    await user.click(screen.getByRole("button", { name: "Send" }))

    await waitFor(() => {
      expect(handleSubmit).toHaveBeenCalledWith({
        name: "John Doe",
        email: "john@example.com",
        topic: undefined,
        message: "This is a test message for support.",
        user: undefined,
        context: undefined,
        metadata: undefined,
      })
    })
  })

  it("shows success message after submission", async () => {
    const user = userEvent.setup()
    render(
      <Contact
        showName={false}
        showEmail={false}
        showTopic={false}
        onSubmit={vi.fn()}
      />
    )

    await user.click(screen.getByRole("button"))
    await user.type(screen.getByLabelText("Message"), "This is a test message.")
    await user.click(screen.getByRole("button", { name: "Send" }))

    await waitFor(() => {
      expect(screen.getByText("Thanks! We'll be in touch soon.")).toBeInTheDocument()
    })
  })

  it("renders topic dropdown", async () => {
    const user = userEvent.setup()
    render(<Contact variant="modal" onSubmit={vi.fn()} />)

    await user.click(screen.getByRole("button"))

    expect(screen.getByRole("combobox")).toBeInTheDocument()
    expect(screen.getByText("Select a topic")).toBeInTheDocument()
  })
})
