import React from "react";
import { ImagePromoBar } from "./index";
import { ImagePromoBarProps } from "./types";

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

jest.mock("../button", () => ({
  __esModule: true,
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  Button: ({ buttonLabel, disableAnimation, ...rest }: any) => (
    <button
      data-testid="cta-button"
      data-disable-animation={String(disableAnimation)}
    >
      {buttonLabel || "CTA"}
    </button>
  ),
  default: ({ buttonLabel, disableAnimation }: any) => (
    <button
      data-testid="cta-button"
      data-disable-animation={String(disableAnimation)}
    >
      {buttonLabel || "CTA"}
    </button>
  ),
}));

jest.mock("@shared/components/video-link", () => ({
  VideoLink: ({ videoLink }: any) => (
    <div
      data-testid="video-link"
      data-link={videoLink?.link || videoLink?.videoAssetUrl || ""}
    />
  ),
}));

jest.mock("@shared/components/checklist", () => ({
  Checklist: ({ items }: any) => (
    <ul data-testid="checklist">
      {items.map((i: string, idx: number) => (
        <li key={idx}>{i}</li>
      ))}
    </ul>
  ),
}));

jest.mock("@shared/components/image", () => ({
  Image: ({ src, alt }: any) => <img data-testid="image" src={src} alt={alt} />,
}));

jest.mock("@shared/components/link", () => ({
  Link: ({ children, href }: any) => (
    <a data-testid="image-link" href={href}>
      {children}
    </a>
  ),
}));

jest.mock("@shared/components/next-image", () => ({
  NextImage: ({ src, alt }: any) => (
    <img data-testid="next-image" src={src} alt={alt} />
  ),
}));

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

jest.mock("@shared/utils", () => ({
  cx: (...args: any[]) => args.filter(Boolean).join(" "),
}));

const defaultProps: ImagePromoBarProps = {
  brow: "",
  enableHeading: false,
  title: "",
  subTitle: "",
  image: "",
  imageWidth: 660,
  imageHeight: 660,
  mediaPosition: true,
  description: null,
  openDescriptionLinksOnANewTab: false,
  checklist: [],
  disclaimer: null,
  imageLinks: [],
  cta: null,
  secondaryCta: null,
  ctaDisclaimer: null,
  maxWidth: true,
  color: "light",
};

describe("ImagePromoBar", () => {
  describe("Text content", () => {
    it("renders brow text when provided", () => {
      render(<ImagePromoBar {...defaultProps} brow="New" />);
      expect(screen.getByText("New")).toBeInTheDocument();
    });

    it("renders title as h2 when enableHeading is false", () => {
      render(<ImagePromoBar {...defaultProps} title="Title" />);
      expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent(
        "Title"
      );
    });

    it("renders title as h1 when enableHeading is true", () => {
      render(
        <ImagePromoBar {...defaultProps} title="Title" enableHeading={true} />
      );
      expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent(
        "Title"
      );
    });

    it("renders subTitle as h3 when enableHeading is false", () => {
      render(<ImagePromoBar {...defaultProps} subTitle="Sub" />);
      expect(screen.getByRole("heading", { level: 3 })).toHaveTextContent(
        "Sub"
      );
    });

    it("renders subTitle as h2 when enableHeading is true", () => {
      render(
        <ImagePromoBar {...defaultProps} subTitle="Sub" enableHeading={true} />
      );
      expect(screen.getByText("Sub").tagName).toBe("H2");
    });

    it("renders description", () => {
      render(<ImagePromoBar {...defaultProps} description="Desc text" />);
      expect(screen.getByText("Desc text")).toBeInTheDocument();
    });

    it("renders ctaDisclaimer and disclaimer", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          ctaDisclaimer="Discl1"
          disclaimer="Discl2"
        />
      );
      expect(screen.getByText("Discl1")).toBeInTheDocument();
      expect(screen.getByText("Discl2")).toBeInTheDocument();
    });
  });

  describe("Color and layout", () => {
    it("applies text-white for light color", () => {
      const { container } = render(
        <ImagePromoBar {...defaultProps} color="light" />
      );
      expect(container.querySelector(".text-white")).toBeInTheDocument();
    });

    it("applies text-text for dark color", () => {
      const { container } = render(
        <ImagePromoBar {...defaultProps} color="dark" />
      );
      expect(container.querySelector(".text-text")).toBeInTheDocument();
    });

    it("applies max-w-120 when maxWidth is true", () => {
      const { container } = render(
        <ImagePromoBar {...defaultProps} maxWidth={true} />
      );
      expect(container.querySelector(".max-w-120")).toBeInTheDocument();
    });

    it("does not apply max-w-120 when maxWidth is false", () => {
      const { container } = render(
        <ImagePromoBar {...defaultProps} maxWidth={false} />
      );
      expect(container.querySelector(".max-w-120")).not.toBeInTheDocument();
    });

    it("applies lg:flex-row-reverse when mediaPosition is true", () => {
      const { container } = render(
        <ImagePromoBar {...defaultProps} mediaPosition={true} />
      );
      expect(container.innerHTML).toContain("xl:flex-row-reverse");
    });

    it("applies lg:flex-row when mediaPosition is false", () => {
      const { container } = render(
        <ImagePromoBar {...defaultProps} mediaPosition={false} />
      );
      expect(container.innerHTML).toContain("xl:flex-row");
      expect(container.innerHTML).not.toContain("xl:flex-row-reverse");
    });
  });

  describe("Checklist", () => {
    it("renders checklist when items exist", () => {
      render(
        <ImagePromoBar {...defaultProps} checklist={["Item 1", "Item 2"]} />
      );
      expect(screen.getByTestId("checklist")).toBeInTheDocument();
    });

    it("does not render checklist when empty", () => {
      render(<ImagePromoBar {...defaultProps} checklist={[]} />);
      expect(screen.queryByTestId("checklist")).not.toBeInTheDocument();
    });
  });

  describe("Image links", () => {
    it("renders image links when provided", () => {
      const imageLinks = [
        { url: "https://a.com", image: "https://img.test/a.png" },
        { url: "https://b.com", image: "https://img.test/b.png" },
      ];
      render(<ImagePromoBar {...defaultProps} imageLinks={imageLinks} />);
      const links = screen.getAllByTestId("image-link");
      expect(links).toHaveLength(2);
      expect(links[0]).toHaveAttribute("href", "https://a.com");
    });
  });

  describe("CTAs", () => {
    it("renders primary CTA", () => {
      render(<ImagePromoBar {...defaultProps} cta={{ buttonLabel: "Buy" }} />);
      expect(screen.getByTestId("cta-button")).toBeInTheDocument();
    });

    it("renders both CTAs", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          cta={{ buttonLabel: "Primary" }}
          secondaryCta={{ buttonLabel: "Secondary" }}
        />
      );
      expect(screen.getAllByTestId("cta-button")).toHaveLength(2);
    });

    it("does not render CTA section when neither provided", () => {
      const { container } = render(<ImagePromoBar {...defaultProps} />);
      expect(container.querySelector(".primary-cta")).not.toBeInTheDocument();
    });

    it("keeps disableAnimation true on both CTAs by default", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          cta={{ buttonLabel: "Primary" }}
          secondaryCta={{ buttonLabel: "Secondary" }}
        />
      );
      const buttons = screen.getAllByTestId("cta-button");
      expect(buttons).toHaveLength(2);
      buttons.forEach(button => {
        expect(button).toHaveAttribute("data-disable-animation", "true");
      });
    });

    it("passes disableAnimation false to both CTAs when enableAnimation is true", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          cta={{ buttonLabel: "Primary" }}
          secondaryCta={{ buttonLabel: "Secondary" }}
          enableAnimation={true}
        />
      );
      const buttons = screen.getAllByTestId("cta-button");
      expect(buttons).toHaveLength(2);
      buttons.forEach(button => {
        expect(button).toHaveAttribute("data-disable-animation", "false");
      });
    });
  });

  describe("Image", () => {
    it("renders the plain image when there is no videoLink content", () => {
      render(
        <ImagePromoBar {...defaultProps} image="https://img.test/hero.jpg" />
      );
      expect(screen.getByTestId("next-image")).toHaveAttribute(
        "src",
        "https://img.test/hero.jpg"
      );
    });

    it("does not render the image section when image is empty", () => {
      render(<ImagePromoBar {...defaultProps} image="" />);
      expect(screen.queryByTestId("next-image")).not.toBeInTheDocument();
    });

    it("does not render the plain image when videoLink has a valid href", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          image="https://img.test/hero.jpg"
          videoLink={{ link: "https://youtube.com/watch?v=123" }}
        />
      );
      expect(screen.queryByTestId("next-image")).not.toBeInTheDocument();
    });

    it("does not render the plain image when videoLink has its own poster image, even without a valid href", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          image="https://img.test/hero.jpg"
          videoLink={{ image: "thumb.jpg" }}
        />
      );
      expect(screen.queryByTestId("next-image")).not.toBeInTheDocument();
    });

    it("renders the plain image when no videoLink is attached at all", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          image="https://img.test/hero.jpg"
          videoLink={undefined}
        />
      );
      expect(screen.getByTestId("next-image")).toBeInTheDocument();
    });

    it("suppresses the plain image when an empty videoLink object is attached (VideoLink owns its own fallback from there)", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          image="https://img.test/hero.jpg"
          videoLink={{}}
        />
      );
      expect(screen.queryByTestId("next-image")).not.toBeInTheDocument();
    });
  });

  describe("Video", () => {
    it("always renders VideoLink, passing videoLink through", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          videoLink={{
            link: "https://youtube.com/watch?v=123",
            image: "thumb.jpg",
          }}
        />
      );
      expect(screen.getByTestId("video-link")).toBeInTheDocument();
    });

    it("passes the videoLink prop through to VideoLink", () => {
      render(
        <ImagePromoBar
          {...defaultProps}
          videoLink={{ link: "https://vimeo.com/123", image: "thumb.jpg" }}
        />
      );
      expect(screen.getByTestId("video-link")).toHaveAttribute(
        "data-link",
        "https://vimeo.com/123"
      );
    });

    it("still renders VideoLink when videoLink has no valid href (VideoLink owns its own poster fallback)", () => {
      render(<ImagePromoBar {...defaultProps} videoLink={{}} />);
      expect(screen.getByTestId("video-link")).toBeInTheDocument();
    });
  });
});
