import "@testing-library/jest-dom";

import React from "react";
import { CtaCallout } from "./index";
import { CtaCalloutProps } from "./types";

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

jest.mock("@shared/components/text", () => ({
  Text: ({ children, as, ...props }: any) => {
    const Tag = as || "span";
    return <Tag {...props}>{children}</Tag>;
  },
}));

jest.mock("@shared/contentful/blocks/button", () => ({
  Button: (props: any) => (
    <button
      data-testid="cta-button"
      data-size={JSON.stringify(props.size)}
      data-href={props.href}
    >
      {props.buttonLabel || props.children}
    </button>
  ),
}));

describe("CtaCallout", () => {
  const defaultProps: CtaCalloutProps = {
    title: "Get Started Today",
    subTitle: "Best Internet Plans",
    description: <p>Choose the plan that works for you.</p>,
    button: { buttonLabel: "Shop Now", href: "/shop" },
    background: "white",
    color: "dark",
    contentAlignment: "center",
    descriptionAlignment: "center",
  };

  it("renders the component", () => {
    const { container } = render(<CtaCallout {...defaultProps} />);
    expect(container.firstChild).toBeInTheDocument();
  });

  it("renders title as h2 by default", () => {
    render(<CtaCallout {...defaultProps} />);
    const title = screen.getByText("Get Started Today");
    expect(title.tagName).toBe("H2");
  });

  it("renders title as h1 when enableHeading is true", () => {
    render(<CtaCallout {...defaultProps} enableHeading={true} />);
    const title = screen.getByText("Get Started Today");
    expect(title.tagName).toBe("H1");
  });

  it("renders subtitle as h3", () => {
    render(<CtaCallout {...defaultProps} />);
    const subtitle = screen.getByText("Best Internet Plans");
    expect(subtitle.tagName).toBe("H3");
  });

  it("renders description", () => {
    render(<CtaCallout {...defaultProps} />);
    expect(
      screen.getByText("Choose the plan that works for you.")
    ).toBeInTheDocument();
  });

  it("renders the button", () => {
    render(<CtaCallout {...defaultProps} />);
    expect(screen.getByTestId("cta-button")).toBeInTheDocument();
  });

  it("does not render title when not provided", () => {
    render(<CtaCallout {...defaultProps} title={undefined} />);
    expect(screen.queryByText("Get Started Today")).not.toBeInTheDocument();
  });

  it("does not render subtitle when not provided", () => {
    render(<CtaCallout {...defaultProps} subTitle={undefined} />);
    expect(screen.queryByText("Best Internet Plans")).not.toBeInTheDocument();
  });

  it("does not render description when not provided", () => {
    render(<CtaCallout {...defaultProps} description={undefined} />);
    expect(
      screen.queryByText("Choose the plan that works for you.")
    ).not.toBeInTheDocument();
  });

  describe("background colors", () => {
    it("applies white background class", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} background="white" />
      );
      expect(container.firstChild).toHaveClass("bg-bg");
    });

    it("applies navy background class", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} background="navy" />
      );
      expect(container.firstChild).toHaveClass("bg-bg-fill-inverse");
    });

    it("applies blue background class", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} background="blue" />
      );
      expect(container.firstChild).toHaveClass("bg-bg-fill-brand");
    });

    it("applies green background class", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} background="green" />
      );
      expect(container.firstChild).toHaveClass("bg-bg-fill-success");
    });

    it("applies purple background class", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} background="purple" />
      );
      expect(container.firstChild).toHaveClass("bg-bg-fill-brand-tertiary");
    });

    it("applies yellow background class", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} background="yellow" />
      );
      expect(container.firstChild).toHaveClass("bg-bg-fill-brand-accent");
    });
  });

  describe("text colors", () => {
    it("applies dark text color", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} color="dark" />
      );
      const inner = container.querySelector(".flex.flex-col");
      expect(inner?.className).toContain("text-text");
    });

    it("applies light text color", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} color="light" />
      );
      const inner = container.querySelector(".flex.flex-col");
      expect(inner?.className).toContain("text-text-inverse");
    });
  });

  describe("alignment", () => {
    it("applies content alignment to title", () => {
      render(<CtaCallout {...defaultProps} contentAlignment="left" />);
      const title = screen.getByText("Get Started Today");
      expect(title.className).toContain("text-left");
    });

    it("applies content alignment to subtitle", () => {
      render(<CtaCallout {...defaultProps} contentAlignment="right" />);
      const subtitle = screen.getByText("Best Internet Plans");
      expect(subtitle.className).toContain("text-right");
    });

    it("applies description alignment", () => {
      render(<CtaCallout {...defaultProps} descriptionAlignment="left" />);
      const descWrapper = screen
        .getByText("Choose the plan that works for you.")
        .closest("div");
      expect(descWrapper?.className).toContain("text-left");
    });
  });

  describe("maxWidth", () => {
    it("applies max-w-120 when maxWidth is true (default)", () => {
      const { container } = render(<CtaCallout {...defaultProps} />);
      const inner = container.querySelector(".flex.flex-col");
      expect(inner?.className).toContain("max-w-120");
      expect(inner?.className).toContain("mx-auto");
    });

    it("does not apply max-w-120 when maxWidth is false", () => {
      const { container } = render(
        <CtaCallout {...defaultProps} maxWidth={false} />
      );
      const inner = container.querySelector(".flex.flex-col");
      expect(inner?.className).not.toContain("max-w-120");
    });
  });

  describe("button props", () => {
    it("passes button props to Button component", () => {
      render(<CtaCallout {...defaultProps} />);
      const button = screen.getByTestId("cta-button");
      expect(button).toHaveAttribute("data-href", "/shop");
    });

    it("passes size prop with base large", () => {
      render(<CtaCallout {...defaultProps} />);
      const button = screen.getByTestId("cta-button");
      expect(button.dataset.size).toContain("large");
    });

    it("passes onModalButtonClick to Button", () => {
      const onModalButtonClick = jest.fn();
      render(
        <CtaCallout {...defaultProps} onModalButtonClick={onModalButtonClick} />
      );
      const button = screen.getByTestId("cta-button");
      expect(button).toBeInTheDocument();
    });

    it("passes renderCheckPlans to Button", () => {
      const renderCheckPlans = jest.fn();
      render(
        <CtaCallout {...defaultProps} renderCheckPlans={renderCheckPlans} />
      );
      const button = screen.getByTestId("cta-button");
      expect(button).toBeInTheDocument();
    });
  });

  describe("section rendering", () => {
    it("has component-container class", () => {
      const { container } = render(<CtaCallout {...defaultProps} />);
      expect(container.firstChild).toHaveClass("component-container");
    });

    it("has correct padding classes", () => {
      const { container } = render(<CtaCallout {...defaultProps} />);
      expect(container.firstChild).toHaveClass("px-5");
      expect(container.firstChild).toHaveClass("py-16");
    });

    it("button container has flex and justify-center", () => {
      render(<CtaCallout {...defaultProps} />);
      const buttonWrapper = screen.getByTestId("cta-button").parentElement;
      expect(buttonWrapper?.className).toContain("flex");
      expect(buttonWrapper?.className).toContain("justify-center");
    });
  });
});
