import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import { TextArea } from "../TextArea";

// id is required
describe("rendering TextArea", () => {
  describe("initial state", () => {
    it("has default class textarea", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" />,
      );
      expect(getByTestId("test-id")).toHaveClass("textarea");
    });
  });
  describe("passed props", () => {
    it("has is-invalid class when isInvalid prop is passed", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" isInvalid />,
      );
      expect(getByTestId("test-id")).toHaveClass("is-invalid");
    });
    it("has is-valid class when isValid prop is passed", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" isValid />,
      );
      expect(getByTestId("test-id")).toHaveClass("is-valid");
    });
    it("has textarea--large class when size prop is set to large", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" size="large" />,
      );
      expect(getByTestId("test-id")).toHaveClass("textarea--large");
    });
    it("has textarea--fullwidth class when width prop is set to fullwidth", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" width="fullwidth" />,
      );
      expect(getByTestId("test-id")).toHaveClass("textarea--fullwidth");
    });
    it("has additional class when className is set", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" className="test-class" />,
      );
      expect(getByTestId("test-id")).toHaveClass("textarea");
      expect(getByTestId("test-id")).toHaveClass("test-class");
    });
    it("name attribute is set to id when name prop is not set", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" />,
      );
      expect(getByTestId("test-id").getAttribute("name")).toBe(
        getByTestId("test-id").getAttribute("id"),
      );
    });
    it("name attribute is set to name prop when prop is passed", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" name="test-name" />,
      );
      expect(getByTestId("test-id").getAttribute("name")).toBe("test-name");
    });
    it("disabled attribute is set to true when isDisabled prop is passed", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" isDisabled />,
      );
      expect(getByTestId("test-id").disabled).toBe(true);
    });
    it("has placeholder attribute when placeholder prop is set", () => {
      const { getByTestId } = render(
        <TextArea
          data-testid="test-id"
          id="test"
          placeholder="test-placeholder"
        />,
      );
      expect(getByTestId("test-id").getAttribute("placeholder")).toBe(
        "test-placeholder",
      );
    });
    it("has value attribute set to value prop", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" defaultValue="test-value" />,
      );
      expect(getByTestId("test-id").value).toBe("test-value");
    });
    it("value is rendered", () => {
      const { getByText } = render(
        <TextArea data-testid="test-id" id="test" defaultValue="test-value" />,
      );
      expect(getByText("test-value")).toBeInTheDocument();
    });
    it("has readOnly attribute set to true when readOnly prop is passed", () => {
      const { getByTestId } = render(
        <TextArea data-testid="test-id" id="test" readOnly />,
      );
      expect(getByTestId("test-id").readOnly).toBe(true);
    });
    it("value attribute can be changed", async () => {
      const user = userEvent.setup();
      render(<TextArea data-testid="test-id" id="test" />);

      const textArea = screen.getByRole("textbox");

      await user.type(textArea, "test value");

      expect(textArea).toHaveValue("test value");
    });
    it("default value attribute can be changed", async () => {
      const user = userEvent.setup();

      render(
        <TextArea
          data-testid="test-id"
          id="test"
          defaultValue="test-default-value"
        />,
      );

      const textArea = screen.getByTestId("test-id");

      await user.clear(textArea);
      await user.type(textArea, "test value");

      expect(textArea).toHaveValue("test value");
    });
  });
});
