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

import { PromotionCard } from "../PromotionCard";

/**
 * PromotionCard Component Unit Tests
 *
 * These unit tests focus on testing individual functionality and behavior
 * of the PromotionCard component in isolation. They cover:
 *
 * 🏗️ COMPONENT STRUCTURE
 * - Default rendering behavior
 * - CSS class application
 * - HTML element rendering
 * - Component initialization
 * - Card wrapper structure
 *
 * 🎨 STYLING & CLASSES
 * - Base CSS class application
 * - Color scheme-based class generation
 * - Custom className merging
 * - Conditional class application
 *
 * 🔧 PROPS HANDLING
 * - Individual prop testing
 * - Prop combinations
 * - Default prop values
 * - Prop validation and fallbacks
 * - Color scheme mapping
 *
 * 📦 CONTENT RENDERING
 * - Children rendering through Card
 * - Text content
 * - JSX content
 * - Empty content handling
 * - Multiple children
 *
 * 🎯 SPECIFIC FUNCTIONALITY
 * - Color scheme prop behavior (light, dark)
 * - Color mapping to Card component
 * - ClassName prop merging
 * - Additional props spreading
 * - Card integration
 *
 * ⚡ PERFORMANCE & OPTIMIZATION
 * - Component re-rendering
 * - Prop change handling
 * - Memory usage patterns
 * - Bundle size impact
 *
 * 🔍 DETAILED ASSERTIONS
 * - Exact class presence/absence
 * - Element count verification
 * - Attribute validation
 * - Content accuracy
 * - DOM structure integrity
 */

describe("PromotionCard Component Unit Tests", () => {
  describe("Component Structure & Initialization", () => {
    it("renders with default structure and base class", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card" />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toBeInTheDocument();
      expect(card).toHaveClass("promotion-card");
      expect(card.tagName.toLowerCase()).toBe("div");
    });

    it("renders as Card component with proper structure", () => {
      const { container } = render(
        <PromotionCard data-testid="test-promotion-card">
          <p>Test content</p>
        </PromotionCard>,
      );
      const card = container.querySelector(
        '[data-testid="test-promotion-card"]',
      );

      expect(card).toBeInTheDocument();
      expect(card).toHaveClass("card"); // Card base class
      expect(card).toHaveClass("promotion-card"); // PromotionCard class
      expect(card).toContainElement(screen.getByText("Test content"));
    });

    it("maintains component structure with various props", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          className="custom-class"
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toBeInTheDocument();
      expect(card).toHaveClass("promotion-card");
      expect(card.tagName.toLowerCase()).toBe("div");
    });
  });

  describe("CSS Classes & Styling", () => {
    it("applies base promotion-card class correctly", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card" />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("promotion-card");
    });

    it("merges custom className with base classes", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          className="custom-class"
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("card");
      expect(card).toHaveClass("promotion-card");
      expect(card).toHaveClass("custom-class");
    });

    it("handles multiple custom classes", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          className="class1 class2 class3"
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("promotion-card");
      expect(card).toHaveClass("class1");
      expect(card).toHaveClass("class2");
      expect(card).toHaveClass("class3");
    });

    it("handles empty className gracefully", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card" className="" />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("promotion-card");
    });
  });

  describe("Content Rendering", () => {
    it("renders text children correctly through Card", () => {
      render(
        <PromotionCard data-testid="test-promotion-card">
          Simple text content
        </PromotionCard>,
      );

      expect(screen.getByText("Simple text content")).toBeInTheDocument();
    });

    it("renders JSX children correctly through Card", () => {
      render(
        <PromotionCard data-testid="test-promotion-card">
          <h1>Title</h1>
          <p>Paragraph content</p>
        </PromotionCard>,
      );

      expect(screen.getByText("Title")).toBeInTheDocument();
      expect(screen.getByText("Paragraph content")).toBeInTheDocument();
    });

    it("renders multiple children correctly through Card", () => {
      render(
        <PromotionCard data-testid="test-promotion-card">
          <div>Child 1</div>
          <div>Child 2</div>
          <div>Child 3</div>
        </PromotionCard>,
      );

      expect(screen.getByText("Child 1")).toBeInTheDocument();
      expect(screen.getByText("Child 2")).toBeInTheDocument();
      expect(screen.getByText("Child 3")).toBeInTheDocument();
    });

    it("renders complex nested JSX correctly through Card", () => {
      render(
        <PromotionCard data-testid="test-promotion-card">
          <header>
            <h1>Promotion Header</h1>
            <nav>
              <ul>
                <li>
                  <a href="#offer">Offer</a>
                </li>
                <li>
                  <a href="#details">Details</a>
                </li>
              </ul>
            </nav>
          </header>
          <main>
            <article>
              <h2>Special Offer</h2>
              <p>
                Limited time offer with <strong>50% discount</strong>.
              </p>
            </article>
          </main>
        </PromotionCard>,
      );

      expect(screen.getByText("Promotion Header")).toBeInTheDocument();
      expect(screen.getByText("Offer")).toBeInTheDocument();
      expect(screen.getByText("Details")).toBeInTheDocument();
      expect(screen.getByText("Special Offer")).toBeInTheDocument();
      expect(screen.getByText(/Limited time offer with/)).toBeInTheDocument();
      expect(screen.getByText("50% discount")).toBeInTheDocument();
    });

    it("handles empty children gracefully", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card" />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toBeInTheDocument();
      expect(card.children.length).toBe(0);
    });

    it("handles null children gracefully", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card">{null}</PromotionCard>,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toBeInTheDocument();
    });

    it("handles undefined children gracefully", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card">
          {undefined}
        </PromotionCard>,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toBeInTheDocument();
    });
  });

  describe("Props Combinations", () => {
    it("combines color and className correctly", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          color="background-contrast"
          className="custom-class"
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("promotion-card");
      expect(card).toHaveClass("background-contrast");
      expect(card).toHaveClass("text-inverse");
      expect(card).toHaveClass("custom-class");
    });

    it("combines all props correctly", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          color="background-primary"
          className="custom-class"
          id="promotion-id"
        >
          <h1>Content</h1>
        </PromotionCard>,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("promotion-card");
      expect(card).toHaveClass("custom-class");
      expect(card).toHaveAttribute("id", "promotion-id");
      expect(screen.getByText("Content")).toBeInTheDocument();
    });
  });

  describe("Additional Props Spreading", () => {
    it("passes through id attribute", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card" id="promotion-id" />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveAttribute("id", "promotion-id");
    });

    it("passes through role attribute", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card" role="banner" />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveAttribute("role", "banner");
    });

    it("passes through aria attributes", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          aria-label="Special promotion"
          aria-describedby="promotion-description"
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveAttribute("aria-label", "Special promotion");
      expect(card).toHaveAttribute("aria-describedby", "promotion-description");
    });

    it("passes through data attributes", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          data-custom="value"
          data-promotion="special"
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveAttribute("data-custom", "value");
      expect(card).toHaveAttribute("data-promotion", "special");
    });

    it("passes through event handlers", () => {
      const handleClick = vi.fn();
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          onClick={handleClick}
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toBeInTheDocument();
      // Event handler is attached but not tested here as it's unit test
    });
  });

  describe("Edge Cases & Error Handling", () => {
    it("handles invalid color prop gracefully", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          color="invalid-color"
        />,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("promotion-card");
      // Should still render with the color class provided
      expect(card).toHaveClass("invalid-color");
    });

    it("handles boolean children", () => {
      const { getByTestId } = render(
        <PromotionCard data-testid="test-promotion-card">{true}</PromotionCard>,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toBeInTheDocument();
    });

    it("handles number children", () => {
      render(
        <PromotionCard data-testid="test-promotion-card">42</PromotionCard>,
      );

      expect(screen.getByText("42")).toBeInTheDocument();
    });

    it("handles array children", () => {
      render(
        <PromotionCard data-testid="test-promotion-card">
          {["Item 1", "Item 2", "Item 3"]}
        </PromotionCard>,
      );

      expect(screen.getByText(/Item 1/)).toBeInTheDocument();
      expect(screen.getByText(/Item 2/)).toBeInTheDocument();
      expect(screen.getByText(/Item 3/)).toBeInTheDocument();
    });
  });

  describe("Card Integration", () => {
    it("properly integrates with Card component", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          color="background-contrast"
        >
          <div>Card content</div>
        </PromotionCard>,
      );
      const card = getByTestId("test-promotion-card");

      // Should have both Card and PromotionCard classes
      expect(card).toHaveClass("card");
      expect(card).toHaveClass("promotion-card");

      // Should have color classes from Card
      expect(card).toHaveClass("background-contrast");
      expect(card).toHaveClass("text-inverse");
    });

    it("passes props correctly to Card component", () => {
      const { getByTestId } = render(
        <PromotionCard
          data-testid="test-promotion-card"
          color="background-primary"
          noBorder={true}
        >
          <div>Card content</div>
        </PromotionCard>,
      );
      const card = getByTestId("test-promotion-card");

      expect(card).toHaveClass("card");
      expect(card).toHaveClass("promotion-card");
      expect(card).toHaveClass("card--no-border");
    });
  });
});
