import { composeStories } from "@storybook/react"
import { screen } from "@testing-library/react"
import { userEvent } from "@testing-library/user-event"
import React from "react"
import { expect, vitest, describe, test } from "vitest"
import { render } from "../../../tests/render"
import { ChevronLeft } from "../../icons"
import * as stories from "./Button.stories"

const { Default, WithLinkAndTooltip } = composeStories(stories)

describe("<Button />", () => {
  describe("enabled", () => {
    test("as button", async () => {
      const onClick = vitest.fn()
      render(<Default onClick={onClick} />)
      const button = screen.getByRole("button", { name: "Click me" })
      expect(button).toBeEnabled()
      await userEvent.click(button)
      expect(onClick).toHaveBeenCalled()
    })

    test("as link", async () => {
      const onClick = vitest.fn()
      render(<Default href="https://opensea.io" onClick={onClick} />)
      const button = screen.getByRole("link", { name: "Click me" })
      expect(button).toHaveAttribute("href", "https://opensea.io/")
      await userEvent.click(button)
      expect(onClick).toHaveBeenCalled()
    })

    test("with link & tooltip", async () => {
      render(<WithLinkAndTooltip />)

      const button = screen.getByRole("link", { name: "Click me" })
      await userEvent.hover(button)
      await screen.findAllByText("Tooltip text")
    })

    test("as icon", () => {
      render(<Default aria-label="Next" icon={ChevronLeft} />)
      const button = screen.getByRole("button", { name: "Next" })
      expect(button).toHaveAttribute("aria-label", "Next")
      expect(button.querySelector("svg")?.parentElement).toHaveAttribute(
        "aria-hidden",
        "true",
      )
    })
  })

  describe("disabled", () => {
    test("as button", async () => {
      const onClick = vitest.fn()
      render(<Default disabled onClick={onClick} />)
      const button = screen.getByRole("button", { name: "Click me" })
      expect(button).toBeDisabled()
      expect(button).toHaveAttribute("type", "button")
      expect(button).toHaveClass("pointer-events-none")
      expect(button).toHaveClass("opacity-40")
      await userEvent.click(button)
      expect(onClick).not.toHaveBeenCalled()
    })

    test("as link", () => {
      const onClick = vitest.fn()
      render(<Default disabled href="https://opensea.io" onClick={onClick} />)
      const button = screen.getByRole("link", { name: "Click me" })
      expect(button).toHaveAttribute("href", "https://opensea.io/")
      expect(button).toHaveAttribute("aria-disabled", "true")
      expect(button).toHaveAttribute("tabindex", "-1")
      expect(button).toHaveClass("pointer-events-none")
      expect(button).toHaveClass("opacity-40")
      expect(button).not.toHaveAttribute("type", "button")
      expect(onClick).not.toHaveBeenCalled()
    })
  })
})
