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

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

jest.mock("framer-motion", () => ({
  motion: {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    div: ({ children, className, ...rest }: any) => (
      <div className={className}>{children}</div>
    ),
  },
}));

jest.mock("@radix-ui/react-dialog", () => ({
  Root: ({ open, onOpenChange, children }: any) => (
    <div
      data-testid="dialog-root"
      data-open={open}
      onClick={() => open && onOpenChange?.()}
    >
      {children}
    </div>
  ),
  Portal: ({ children }: any) => (
    <div data-testid="dialog-portal">{children}</div>
  ),
  Overlay: () => <div data-testid="dialog-overlay" />,
  Content: ({ children, className, style, onOpenAutoFocus }: any) => {
    // Call onOpenAutoFocus to cover that branch
    if (onOpenAutoFocus) {
      const mockEvent = { preventDefault: jest.fn() };
      onOpenAutoFocus(mockEvent);
    }
    return (
      <div data-testid="dialog-content" className={className} style={style}>
        {children}
      </div>
    );
  },
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  Close: ({ children, asChild }: any) => (
    <div data-testid="dialog-close">{children}</div>
  ),
}));

jest.mock("@shared/components/material-icon", () => ({
  MaterialIcon: ({ name }: any) => (
    <span data-testid="material-icon">{name}</span>
  ),
}));

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: ({ children, buttonClassName, showButtonAs }: any) => (
    <button data-testid="close-button" className={buttonClassName}>
      {children}
    </button>
  ),
}));

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

describe("Modal", () => {
  const defaultProps = { isOpen: true, onRequestClose: jest.fn() };

  beforeEach(() => jest.clearAllMocks());

  describe("Rendering", () => {
    it("renders dialog root with open state", () => {
      render(<Modal {...defaultProps} />);
      expect(screen.getByTestId("dialog-root")).toHaveAttribute(
        "data-open",
        "true"
      );
    });

    it("renders close button with MaterialIcon", () => {
      render(<Modal {...defaultProps} />);
      expect(screen.getByTestId("close-button")).toBeInTheDocument();
      expect(screen.getByText("close")).toBeInTheDocument();
    });

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

    it("does not render title when not provided", () => {
      render(<Modal {...defaultProps} />);
      expect(screen.queryByRole("heading")).not.toBeInTheDocument();
    });

    it("renders description when provided", () => {
      render(<Modal {...defaultProps} description="Some desc" />);
      expect(screen.getByText("Some desc")).toBeInTheDocument();
    });

    it("does not render description when not provided", () => {
      const { container } = render(<Modal {...defaultProps} />);
      expect(container.querySelector(".mb-8")).not.toBeInTheDocument();
    });

    it("renders content", () => {
      render(
        <Modal
          {...defaultProps}
          content={<div data-testid="content">Content</div>}
        />
      );
      expect(screen.getByTestId("content")).toBeInTheDocument();
    });

    it("renders children", () => {
      render(
        <Modal {...defaultProps}>
          <span data-testid="child">Child</span>
        </Modal>
      );
      expect(screen.getByTestId("child")).toBeInTheDocument();
    });

    it("does not render children placeholder when not provided", () => {
      const { container } = render(<Modal {...defaultProps} />);
      expect(container.innerHTML).not.toContain("null");
    });
  });

  describe("Size", () => {
    it("applies lg maxWidth by default", () => {
      render(<Modal {...defaultProps} />);
      expect(screen.getByTestId("dialog-content").style.maxWidth).toBe(
        "1024px"
      );
    });

    it("applies sm maxWidth", () => {
      render(<Modal {...defaultProps} size="sm" />);
      expect(screen.getByTestId("dialog-content").style.maxWidth).toBe("640px");
    });

    it("applies xl maxWidth", () => {
      render(<Modal {...defaultProps} size="xl" />);
      expect(screen.getByTestId("dialog-content").style.maxWidth).toBe(
        "1280px"
      );
    });
  });

  describe("Props", () => {
    it("applies bodyClassName to content", () => {
      render(<Modal {...defaultProps} bodyClassName="custom-body" />);
      expect(screen.getByTestId("dialog-content").className).toContain(
        "custom-body"
      );
    });

    it("applies type and index as data attributes", () => {
      render(<Modal {...defaultProps} type="tabmodal" index={2} />);
      const section = screen
        .getByTestId("dialog-content")
        .querySelector("[data-section-type]");
      expect(section).toHaveAttribute("data-section-type", "tabmodal");
      expect(section).toHaveAttribute("data-section-index", "2");
    });

    it("defaults type to modal and index to 0", () => {
      render(<Modal {...defaultProps} />);
      const section = screen
        .getByTestId("dialog-content")
        .querySelector("[data-section-type]");
      expect(section).toHaveAttribute("data-section-type", "modal");
      expect(section).toHaveAttribute("data-section-index", "0");
    });
  });

  describe("Close behavior", () => {
    it("calls onRequestClose when dialog onOpenChange triggers while open", () => {
      render(<Modal {...defaultProps} />);
      fireEvent.click(screen.getByTestId("dialog-root"));
      expect(defaultProps.onRequestClose).toHaveBeenCalled();
    });

    it("does not call onRequestClose when isOpen is false", () => {
      render(
        <Modal isOpen={false} onRequestClose={defaultProps.onRequestClose} />
      );
      fireEvent.click(screen.getByTestId("dialog-root"));
      expect(defaultProps.onRequestClose).not.toHaveBeenCalled();
    });

    it("handles missing onRequestClose gracefully", () => {
      expect(() => {
        render(<Modal isOpen={true} />);
        fireEvent.click(screen.getByTestId("dialog-root"));
      }).not.toThrow();
    });
  });
});
