import React from "react";
import { FloatingBanner } from "./index";
import { FloatingBannerProps } from "./types";

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

// Mock dependencies
jest.mock("@shared/components/next-image", () => ({
  NextImage: ({
    src,
    alt,
    width,
    height,
  }: {
    src: string;
    alt: string;
    width: number;
    height: number;
  }) => <img src={src} alt={alt} width={width} height={height} />,
}));

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

jest.mock("@shared/contentful/blocks/button", () => ({
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  Button: ({ buttonLabel, buttonVariant, size, ...rest }: any) => (
    <button data-testid="cta-button">{buttonLabel || "CTA"}</button>
  ),
}));

const defaultProps: FloatingBannerProps = {
  title: "Special Offer",
  subtitle: "Limited Time",
  description: "Get the best deals now",
  disclaimer: "Terms and conditions apply",
  icon: "https://example.com/icon.png",
  cta: { buttonLabel: "Shop Now", href: "/shop" },
};

describe("FloatingBanner", () => {
  describe("Rendering", () => {
    it("renders with all props", () => {
      render(<FloatingBanner {...defaultProps} />);
      expect(screen.getByText("Special Offer")).toBeInTheDocument();
      expect(screen.getByText("Limited Time")).toBeInTheDocument();
      expect(screen.getByText("Get the best deals now")).toBeInTheDocument();
      expect(
        screen.getByText("Terms and conditions apply")
      ).toBeInTheDocument();
    });

    it("renders with no optional props", () => {
      const { container } = render(<FloatingBanner />);
      expect(container.firstChild).toBeInTheDocument();
    });

    it("renders title when provided", () => {
      render(<FloatingBanner title="Banner Title" />);
      expect(screen.getByText("Banner Title")).toBeInTheDocument();
    });

    it("does not render title when not provided", () => {
      render(<FloatingBanner subtitle="Sub" />);
      expect(screen.queryByText("Banner Title")).not.toBeInTheDocument();
    });

    it("renders subtitle when provided", () => {
      render(<FloatingBanner subtitle="Sub Text" />);
      expect(screen.getByText("Sub Text")).toBeInTheDocument();
    });

    it("does not render subtitle when not provided", () => {
      render(<FloatingBanner title="Title" />);
      expect(screen.queryByText("Sub Text")).not.toBeInTheDocument();
    });

    it("renders description when provided", () => {
      render(<FloatingBanner description="Desc here" />);
      expect(screen.getByText("Desc here")).toBeInTheDocument();
    });

    it("does not render description when not provided", () => {
      render(<FloatingBanner title="Title" />);
      expect(screen.queryByText("Desc here")).not.toBeInTheDocument();
    });

    it("renders disclaimer when provided", () => {
      render(<FloatingBanner disclaimer="Disclaimer text" />);
      expect(screen.getByText("Disclaimer text")).toBeInTheDocument();
    });

    it("does not render disclaimer when not provided", () => {
      render(<FloatingBanner title="No Disclaimer" />);
      expect(screen.queryByText("Disclaimer text")).not.toBeInTheDocument();
    });
  });

  describe("Heading levels", () => {
    it("renders title as h2 when enableHeading is false/undefined", () => {
      render(<FloatingBanner title="H2 Title" />);
      const el = screen.getByText("H2 Title");
      expect(el.tagName).toBe("H2");
    });

    it("renders title as h1 when enableHeading is true", () => {
      render(<FloatingBanner title="H1 Title" enableHeading={true} />);
      const el = screen.getByText("H1 Title");
      expect(el.tagName).toBe("H1");
    });

    it("renders subtitle always as h3", () => {
      render(<FloatingBanner subtitle="Always H3" />);
      const el = screen.getByText("Always H3");
      expect(el.tagName).toBe("H3");
    });
  });

  describe("Background themes", () => {
    it("applies navy background by default", () => {
      const { container } = render(<FloatingBanner title="BG" />);
      const bannerInner = container.querySelector(".bg-\\[\\#00002D\\]");
      expect(bannerInner).toBeInTheDocument();
    });

    it.each([
      ["blue", "bg-[#07B2E2]"],
      ["green", "bg-[#26B170]"],
      ["yellow", "bg-[#F5FF1E]"],
      ["purple", "bg-[#931D69]"],
      ["white", "bg-white"],
      ["navy", "bg-[#00002D]"],
    ] as const)("applies %s background class", (bg, expectedClass) => {
      const { container } = render(
        <FloatingBanner title="BG" background={bg} />
      );
      const bannerInner = container.querySelector(
        `.${CSS.escape(expectedClass)}`
      );
      expect(bannerInner).toBeInTheDocument();
    });
  });

  describe("Color theme", () => {
    it("applies light (white) text by default", () => {
      const { container } = render(<FloatingBanner title="Color" />);
      const bannerInner = container.querySelector(".text-white");
      expect(bannerInner).toBeInTheDocument();
    });

    it("applies dark text when color is dark", () => {
      const { container } = render(
        <FloatingBanner title="Color" color="dark" />
      );
      const bannerInner = container.querySelector(".text-text");
      expect(bannerInner).toBeInTheDocument();
    });

    it("applies white text when color is light", () => {
      const { container } = render(
        <FloatingBanner title="Color" color="light" />
      );
      const bannerInner = container.querySelector(".text-white");
      expect(bannerInner).toBeInTheDocument();
    });
  });

  describe("Max width", () => {
    it("applies max-w-120 when maxWidth is true (default)", () => {
      const { container } = render(<FloatingBanner title="Width" />);
      const wrapper = container.querySelector(".max-w-120");
      expect(wrapper).toBeInTheDocument();
    });

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

  describe("Icon", () => {
    it("renders icon image when provided", () => {
      render(<FloatingBanner icon="https://example.com/icon.png" />);
      const img = screen.getByAltText("icon");
      expect(img).toHaveAttribute("src", "https://example.com/icon.png");
      expect(img).toHaveAttribute("width", "80");
      expect(img).toHaveAttribute("height", "80");
    });

    it("does not render icon when not provided", () => {
      render(<FloatingBanner title="No Icon" />);
      expect(screen.queryByAltText("icon")).not.toBeInTheDocument();
    });
  });

  describe("CTA Button", () => {
    it("renders CTA button when cta is provided", () => {
      render(
        <FloatingBanner cta={{ buttonLabel: "Get Started", href: "/start" }} />
      );
      expect(screen.getByTestId("cta-button")).toBeInTheDocument();
    });

    it("does not render CTA button when cta is not provided", () => {
      render(<FloatingBanner title="No CTA" />);
      expect(screen.queryByTestId("cta-button")).not.toBeInTheDocument();
    });

    it("does not render CTA button when cta is null", () => {
      render(<FloatingBanner title="Null CTA" cta={null} />);
      expect(screen.queryByTestId("cta-button")).not.toBeInTheDocument();
    });
  });

  describe("Description as ReactNode", () => {
    it("renders JSX description", () => {
      render(
        <FloatingBanner
          description={
            <span data-testid="jsx-desc">
              Rich <strong>description</strong>
            </span>
          }
        />
      );
      expect(screen.getByTestId("jsx-desc")).toBeInTheDocument();
    });
  });

  describe("Disclaimer as ReactNode", () => {
    it("renders JSX disclaimer", () => {
      render(
        <FloatingBanner
          disclaimer={<span data-testid="jsx-disc">Legal info</span>}
        />
      );
      expect(screen.getByTestId("jsx-disc")).toBeInTheDocument();
    });
  });
});
