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

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

// Mock next/link
jest.mock("next/link", () => {
  const MockLink = ({ children, href, className, ...rest }: any) => (
    <a href={href} className={className} {...rest}>
      {children}
    </a>
  );
  MockLink.displayName = "MockNextLink";
  return MockLink;
});

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

describe("BlogCard", () => {
  const defaultProps = {
    href: "/blog/test-post",
    title: "Test Blog Post",
    description: "A description of the post",
    date: "Jan 15, 2026",
    category: "Technology",
  };

  describe("Rendering", () => {
    it("renders the article element", () => {
      const { container } = render(<BlogCard {...defaultProps} />);
      expect(container.querySelector("article")).toBeInTheDocument();
    });

    it("renders title as a link", () => {
      render(<BlogCard {...defaultProps} />);
      expect(screen.getByText("Test Blog Post")).toBeInTheDocument();
      expect(screen.getByText("Test Blog Post").closest("a")).toHaveAttribute(
        "href",
        "/blog/test-post"
      );
    });

    it("renders description", () => {
      render(<BlogCard {...defaultProps} />);
      expect(screen.getByText("A description of the post")).toBeInTheDocument();
    });

    it("renders category", () => {
      render(<BlogCard {...defaultProps} />);
      expect(screen.getByText("Technology")).toBeInTheDocument();
    });

    it("renders date", () => {
      render(<BlogCard {...defaultProps} />);
      expect(screen.getByText("Jan 15, 2026")).toBeInTheDocument();
    });

    it("renders dot separator between category and date", () => {
      render(<BlogCard {...defaultProps} />);
      expect(screen.getByText("•")).toBeInTheDocument();
    });

    it("does not render date separator when date is not provided", () => {
      render(<BlogCard {...defaultProps} date={undefined} />);
      expect(screen.queryByText("•")).not.toBeInTheDocument();
    });
  });

  describe("Image", () => {
    it("renders img element when image is provided", () => {
      const image = {
        src: "/test.jpg",
        alt: "Test image",
        width: 400,
        height: 300,
      };
      const { container } = render(
        <BlogCard {...defaultProps} image={image} />
      );
      const img = container.querySelector("img");
      expect(img).toBeInTheDocument();
      expect(img).toHaveAttribute("src", "/test.jpg");
      expect(img).toHaveAttribute("alt", "Test image");
    });

    it("renders custom imageComponent when provided", () => {
      const image = {
        src: "/test.jpg",
        alt: "Custom image",
        width: 400,
        height: 300,
      };
      const CustomImage = (props: any) => (
        <img data-testid="custom-image" {...props} />
      );
      render(
        <BlogCard
          {...defaultProps}
          image={image}
          imageComponent={CustomImage}
        />
      );
      expect(screen.getByTestId("custom-image")).toBeInTheDocument();
    });

    it("renders placeholder when no image is provided", () => {
      const { container } = render(<BlogCard {...defaultProps} />);
      const placeholder = container.querySelector("[aria-hidden='true']");
      expect(placeholder).toBeInTheDocument();
    });
  });

  describe("Layout", () => {
    it("applies grid layout by default", () => {
      const { container } = render(<BlogCard {...defaultProps} />);
      const article = container.querySelector("article");
      expect(article?.className).toContain("flex h-full flex-col");
    });

    it("applies non-grid layout when asGrid is false", () => {
      const { container } = render(
        <BlogCard {...defaultProps} asGrid={false} />
      );
      const article = container.querySelector("article");
      expect(article?.className).toContain("callout-card");
    });

    it("applies h-full in non-grid mode for equal height cards", () => {
      const { container } = render(
        <BlogCard {...defaultProps} asGrid={false} />
      );
      const article = container.querySelector("article");
      expect(article?.className).toContain("h-full");
      expect(article?.className).toContain("flex-col");
    });

    it("applies data-section-type attribute", () => {
      const { container } = render(<BlogCard {...defaultProps} />);
      const article = container.querySelector("article");
      expect(article).toHaveAttribute("data-section-type", "blog-card");
    });

    it("applies data-section-index attribute", () => {
      const { container } = render(<BlogCard {...defaultProps} index={2} />);
      const article = container.querySelector("article");
      expect(article).toHaveAttribute("data-section-index", "2");
    });
  });

  describe("Navigation", () => {
    it("renders a link to href when title is missing", () => {
      const { container } = render(
        <BlogCard {...defaultProps} title={undefined} />
      );
      const links = container.querySelectorAll("a");
      expect(links).toHaveLength(1);
      expect(links[0]).toHaveAttribute("href", "/blog/test-post");
    });

    it("renders exactly one link when title is present", () => {
      const { container } = render(<BlogCard {...defaultProps} />);
      const links = container.querySelectorAll("a");
      expect(links).toHaveLength(1);
      expect(links[0]).toHaveAttribute("href", "/blog/test-post");
    });
  });

  describe("Optional props", () => {
    it("renders without title", () => {
      const { container } = render(
        <BlogCard {...defaultProps} title={undefined} />
      );
      expect(container.querySelector("article")).toBeInTheDocument();
    });

    it("renders without description", () => {
      const { container } = render(
        <BlogCard {...defaultProps} description={undefined} />
      );
      expect(container.querySelector("article")).toBeInTheDocument();
    });
  });
});
