import React from "react";
import { VideoLink } from "./index";

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

jest.mock("./contentful-video-embed", () => ({
  ContentfulVideoEmbed: ({ videoAssetUrl, autoplay }: any) => (
    <div
      data-testid="contentful-video-embed"
      data-video-asset-url={videoAssetUrl}
      data-autoplay={autoplay}
    />
  ),
}));

jest.mock("./vimeo-embed", () => ({
  VimeoEmbed: ({ link, autoplay }: any) => (
    <div data-testid="vimeo-embed" data-link={link} data-autoplay={autoplay} />
  ),
}));

jest.mock("./youtube-embed", () => ({
  YoutubeEmbed: ({ link, autoplay }: any) => (
    <div
      data-testid="youtube-embed"
      data-link={link}
      data-autoplay={autoplay}
    />
  ),
}));

jest.mock("./helper", () => ({
  PlayButton: ({ isHovered }: any) => (
    <div data-testid="play-button" data-hovered={isHovered} />
  ),
}));

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

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

const clickVideoSection = (container: HTMLElement) => {
  fireEvent.click(container.querySelector(".video-section")!);
};

describe("VideoLink", () => {
  it("renders nothing when videoLink is undefined", () => {
    const { container } = render(<VideoLink />);
    expect(container.innerHTML).toBe("");
  });

  it("renders nothing when there is no video and no image to fall back to", () => {
    const { container } = render(<VideoLink videoLink={{}} />);
    expect(container.innerHTML).toBe("");
  });

  it("renders the video link's own poster as a static image when there is no video", () => {
    render(<VideoLink videoLink={{ image: "thumb.jpg" }} />);
    const img = screen.getByAltText("section-image");
    expect(img).toHaveAttribute("src", "thumb.jpg");
    expect(screen.queryByTestId("play-button")).not.toBeInTheDocument();
  });

  it("ignores an unrelated fallbackImage-like prop - only videoLink.image is used as the poster", () => {
    const { container } = render(
      // @ts-expect-error - fallbackImage is intentionally not a supported prop
      <VideoLink videoLink={{}} fallbackImage="https://img.test/hero.jpg" />
    );
    expect(container.innerHTML).toBe("");
  });

  it("renders nothing when videoSourceType is 'contentful' but videoAssetUrl is missing and there is no image", () => {
    const { container } = render(
      <VideoLink videoLink={{ videoSourceType: "contentful" }} />
    );
    expect(container.innerHTML).toBe("");
  });

  it("falls back to videoLink.link when videoSourceType is 'contentful' but videoAssetUrl is missing", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          videoSourceType: "contentful",
          link: "https://youtube.com/watch?v=123",
        }}
      />
    );
    clickVideoSection(container);
    expect(screen.getByTestId("youtube-embed")).toHaveAttribute(
      "data-link",
      "https://youtube.com/watch?v=123"
    );
  });

  it("falls back to the poster when videoSourceType is 'contentful' but videoAssetUrl is missing", () => {
    render(
      <VideoLink
        videoLink={{ videoSourceType: "contentful", image: "thumb.jpg" }}
      />
    );
    expect(screen.getByAltText("section-image")).toHaveAttribute(
      "src",
      "thumb.jpg"
    );
  });

  it("renders preview image and play button when videoLink has link and image", () => {
    render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
        }}
      />
    );
    expect(screen.getByTestId("play-button")).toBeInTheDocument();
    expect(screen.getByAltText("Video preview")).toBeInTheDocument();
  });

  it("does not render preview image when videoLink.image is missing", () => {
    render(
      <VideoLink videoLink={{ link: "https://youtube.com/watch?v=123" }} />
    );
    expect(screen.queryByAltText("Video preview")).not.toBeInTheDocument();
  });

  it("shows youtube embed inline on click for a youtube link", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
        }}
      />
    );
    clickVideoSection(container);
    expect(screen.getByTestId("youtube-embed")).toBeInTheDocument();
  });

  it("shows vimeo embed inline on click for a vimeo link", () => {
    const { container } = render(
      <VideoLink
        videoLink={{ link: "https://vimeo.com/123", image: "thumb.jpg" }}
      />
    );
    clickVideoSection(container);
    expect(screen.getByTestId("vimeo-embed")).toBeInTheDocument();
  });

  it("shows the contentful embed when videoSourceType is 'contentful'", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          videoSourceType: "contentful",
          videoAssetUrl: "https://videos.ctfassets.net/space/asset/sample.mp4",
          image: "thumb.jpg",
        }}
      />
    );
    clickVideoSection(container);
    expect(screen.getByTestId("contentful-video-embed")).toHaveAttribute(
      "data-video-asset-url",
      "https://videos.ctfassets.net/space/asset/sample.mp4"
    );
  });

  it("shows popup overlay when videoPopup is true and playing", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
          videoPopup: true,
        }}
      />
    );
    clickVideoSection(container);
    expect(container.querySelector(".fixed")).toBeInTheDocument();
  });

  it("does not render inline embed when videoPopup is true", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
          videoPopup: true,
        }}
      />
    );
    clickVideoSection(container);
    expect(container.querySelector(".fixed")).toBeInTheDocument();
  });

  it("renders inline (not popup) when videoPopup is not provided", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
        }}
      />
    );
    clickVideoSection(container);
    expect(container.querySelector(".fixed")).not.toBeInTheDocument();
    expect(screen.getByTestId("youtube-embed")).toBeInTheDocument();
  });

  it("closes popup on overlay click", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
          videoPopup: true,
        }}
      />
    );
    clickVideoSection(container);
    fireEvent.click(container.querySelector(".fixed")!);
    expect(container.querySelector(".fixed")).not.toBeInTheDocument();
  });

  it("does not close popup when clicking inside the popup content", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
          videoPopup: true,
        }}
      />
    );
    clickVideoSection(container);
    fireEvent.click(container.querySelector(".max-w-6xl")!);
    expect(container.querySelector(".fixed")).toBeInTheDocument();
  });

  it("handles hover state on the video section", () => {
    const { container } = render(
      <VideoLink
        videoLink={{
          link: "https://youtube.com/watch?v=123",
          image: "thumb.jpg",
        }}
      />
    );
    const videoSection = container.querySelector(".video-section")!;
    fireEvent.mouseEnter(videoSection);
    expect(screen.getByTestId("play-button")).toHaveAttribute(
      "data-hovered",
      "true"
    );
    fireEvent.mouseLeave(videoSection);
    expect(screen.getByTestId("play-button")).toHaveAttribute(
      "data-hovered",
      "false"
    );
  });
});
