/* eslint-disable formatjs/no-literal-string-in-jsx */
import { describe, expect, it, vi, afterEach } from "vitest"
import { render, screen, cleanup } from "@testing-library/react"
import userEvent from "@testing-library/user-event"

import { ChipButton } from "./ChipButton"

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

describe("ChipButton accessibility", () => {
  describe("semantic HTML", () => {
    it("uses proper button element", () => {
      render(<ChipButton>Button</ChipButton>)
      const button = screen.getByRole("button")
      expect(button.tagName).toBe("BUTTON")
    })

    it("has accessible button text", () => {
      render(<ChipButton>Filter by price</ChipButton>)
      expect(
        screen.getByRole("button", { name: "Filter by price" })
      ).toBeTruthy()
    })

    it("button type defaults to button (not submit)", () => {
      render(<ChipButton>Not Submit</ChipButton>)
      const button = screen.getByRole("button")
      // React Aria Components Button defaults to type="button"
      expect(button.getAttribute("type")).toBe("button")
    })
  })

  describe("disabled state", () => {
    it("disabled button has disabled attribute", () => {
      render(<ChipButton isDisabled>Disabled</ChipButton>)
      const button = screen.getByRole("button", { name: "Disabled" })
      expect(button).toHaveProperty("disabled", true)
    })

    it("disabled button is not focusable", async () => {
      const user = userEvent.setup()
      render(
        <div>
          <ChipButton isDisabled>Disabled</ChipButton>
          <ChipButton>Enabled</ChipButton>
        </div>
      )

      await user.tab()
      // Focus should skip disabled button and go to enabled one
      expect(document.activeElement).toBe(
        screen.getByRole("button", { name: "Enabled" })
      )
    })
  })

  describe("keyboard navigation", () => {
    it("button is keyboard accessible", async () => {
      const user = userEvent.setup()
      render(<ChipButton>Accessible Button</ChipButton>)

      const button = screen.getByRole("button")
      await user.tab()
      expect(document.activeElement).toBe(button)
    })

    it("multiple buttons maintain logical focus order", async () => {
      const user = userEvent.setup()
      render(
        <div>
          <ChipButton>First</ChipButton>
          <ChipButton>Second</ChipButton>
          <ChipButton>Third</ChipButton>
        </div>
      )

      const firstButton = screen.getByRole("button", { name: "First" })
      const secondButton = screen.getByRole("button", { name: "Second" })
      const thirdButton = screen.getByRole("button", { name: "Third" })

      await user.tab()
      expect(document.activeElement).toBe(firstButton)

      await user.tab()
      expect(document.activeElement).toBe(secondButton)

      await user.tab()
      expect(document.activeElement).toBe(thirdButton)
    })

    it("Enter key activates button", async () => {
      const onPress = vi.fn()
      const user = userEvent.setup()
      render(<ChipButton onPress={onPress}>Activate</ChipButton>)

      await user.tab()
      await user.keyboard("{Enter}")
      expect(onPress).toHaveBeenCalledTimes(1)
    })

    it("Space key activates button", async () => {
      const onPress = vi.fn()
      const user = userEvent.setup()
      render(<ChipButton onPress={onPress}>Activate</ChipButton>)

      await user.tab()
      await user.keyboard(" ")
      expect(onPress).toHaveBeenCalledTimes(1)
    })
  })

  describe("screen reader support", () => {
    it("button has accessible name from content", () => {
      render(<ChipButton>Descriptive Button Text</ChipButton>)
      const button = screen.getByRole("button")
      expect(button.textContent?.trim().length).toBeGreaterThan(0)
    })

    it("button with icon and text has accessible name", () => {
      render(
        <ChipButton>
          <span aria-hidden="true">✓</span>
          Selected Filter
        </ChipButton>
      )
      const button = screen.getByRole("button")
      expect(button.textContent).toContain("Selected Filter")
    })
  })

  describe("selected state accessibility", () => {
    it("selected state is indicated via aria-pressed", () => {
      render(
        <ChipButton selected aria-pressed={true}>
          Selected
        </ChipButton>
      )
      const button = screen.getByRole("button", { name: "Selected" })
      expect(button.getAttribute("aria-pressed")).toBe("true")
    })
  })
})
