import { describe, expect, it, vi, afterEach } from "vitest"
import { render, screen, cleanup, fireEvent } from "@testing-library/react"
import { IntlProvider } from "react-intl"

import { ShowMoreButton } from "./ShowMoreButton"

afterEach(() => {
  cleanup()
})

const renderShowMoreButton = (
  props: React.ComponentProps<typeof ShowMoreButton>
) => {
  return render(
    <IntlProvider locale="en" messages={{}}>
      <ShowMoreButton {...props} />
    </IntlProvider>
  )
}

describe("ShowMoreButton", () => {
  describe("props", () => {
    it("renders with default props", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData })
      expect(screen.getByRole("button")).toBeTruthy()
    })

    it("displays 'Show more' text by default", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData })
      expect(screen.getByText("Show more")).toBeTruthy()
    })

    it("displays 'Show less' text when showLess is true", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData, showLess: true })
      expect(screen.getByText("Show less")).toBeTruthy()
    })

    it("displays custom 'Show more' text when provided", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({
        loadMoreData,
        textShowMore: "Load more items",
      })
      expect(screen.getByText("Load more items")).toBeTruthy()
    })

    it("displays custom 'Show less' text when provided", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({
        loadMoreData,
        showLess: true,
        textShowLess: "Show fewer items",
      })
      expect(screen.getByText("Show fewer items")).toBeTruthy()
    })

    it("calls loadMoreData when clicked", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData })
      const button = screen.getByRole("button")
      // React Aria Components Button uses onPress which listens to click events
      fireEvent.click(button)
      expect(loadMoreData).toHaveBeenCalledTimes(1)
    })

    it("renders down arrow icon when showLess is false", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData, showLess: false })
      const icon = screen.getByTestId("MaterialIcon")
      expect(icon).toBeTruthy()
      expect(icon.getAttribute("data-icon-name")).toBe("keyboard_arrow_down")
    })

    it("renders up arrow icon when showLess is true", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData, showLess: true })
      const icon = screen.getByTestId("MaterialIcon")
      expect(icon).toBeTruthy()
      expect(icon.getAttribute("data-icon-name")).toBe("keyboard_arrow_up")
    })

    it("applies custom variant prop", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData, variant: "Primary" })
      const button = screen.getByRole("button")
      expect(button).toBeTruthy()
    })

    it("applies custom color prop", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData, color: "Inverted" })
      const button = screen.getByRole("button")
      expect(button).toBeTruthy()
    })

    it("applies custom size prop", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({ loadMoreData, size: "lg" })
      const button = screen.getByRole("button")
      expect(button).toBeTruthy()
    })

    it("passes through additional props to Button", () => {
      const loadMoreData = vi.fn()
      renderShowMoreButton({
        loadMoreData,
        "aria-label": "Custom label",
      })
      const button = screen.getByRole("button")
      expect(button.getAttribute("aria-label")).toBe("Custom label")
    })
  })
})
