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

describe("Feedback", () => {
  it("renders trigger button", () => {
    render(<Feedback onSubmit={vi.fn()} />)
    expect(screen.getByRole("button")).toBeInTheDocument()
  })

  it("renders trigger with label when provided", () => {
    render(<Feedback triggerLabel="Send Feedback" onSubmit={vi.fn()} />)
    expect(screen.getByText("Send Feedback")).toBeInTheDocument()
  })

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

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

    expect(screen.getByText("Give us feedback")).toBeInTheDocument()
  })

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

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

    expect(screen.getByRole("dialog")).toBeInTheDocument()
    expect(screen.getByText("Give us feedback")).toBeInTheDocument()
  })

  it("disables submit until sentiment selected", async () => {
    const user = userEvent.setup()
    render(<Feedback onSubmit={vi.fn()} />)

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

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

  it("enables submit after sentiment selection", async () => {
    const user = userEvent.setup()
    render(<Feedback onSubmit={vi.fn()} />)

    await user.click(screen.getByRole("button"))
    await user.click(screen.getByRole("radio", { name: "Satisfied" }))

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

  it("calls onSubmit with feedback data", async () => {
    const user = userEvent.setup()
    const handleSubmit = vi.fn()
    render(
      <Feedback
        user={{ id: "123", email: "test@example.com" }}
        context={{ feature: "test" }}
        captureMetadata={false}
        onSubmit={handleSubmit}
      />
    )

    await user.click(screen.getByRole("button"))
    await user.click(screen.getByRole("radio", { name: "Satisfied" }))
    await user.type(screen.getByRole("textbox"), "Great product!")
    await user.click(screen.getByRole("button", { name: "Submit" }))

    await waitFor(() => {
      expect(handleSubmit).toHaveBeenCalledWith({
        sentiment: "satisfied",
        message: "Great product!",
        user: { id: "123", email: "test@example.com" },
        context: { feature: "test" },
        metadata: undefined,
      })
    })
  })

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

    await user.click(screen.getByRole("button"))
    await user.click(screen.getByRole("radio", { name: "Neutral" }))
    await user.click(screen.getByRole("button", { name: "Submit" }))

    await waitFor(() => {
      expect(screen.getByText("Thanks for your feedback!")).toBeInTheDocument()
    })
  })

  it("uses custom title", async () => {
    const user = userEvent.setup()
    render(<Feedback title="Rate this" onSubmit={vi.fn()} />)

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

    expect(screen.getByText("Rate this")).toBeInTheDocument()
  })
})
