import { EmailInputBlock } from "./index";

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

describe("EmailInputBlock", () => {
  const defaultProps = {
    onSubmit: jest.fn(),
  };

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

  it("renders with default props", () => {
    const { container } = render(<EmailInputBlock {...defaultProps} />);
    expect(container.querySelector("#email-input")).toBeInTheDocument();
  });

  it("renders custom anchorId", () => {
    const { container } = render(
      <EmailInputBlock {...defaultProps} anchorId="custom-anchor" />
    );
    expect(container.querySelector("#custom-anchor")).toBeInTheDocument();
  });

  it("renders title when provided", () => {
    render(<EmailInputBlock {...defaultProps} title="Join us" />);
    expect(screen.getByText("Join us")).toBeInTheDocument();
    expect(screen.getByText("Join us").tagName).toBe("H1");
  });

  it("does not render title when not provided", () => {
    const { container } = render(<EmailInputBlock {...defaultProps} />);
    expect(container.querySelector("h1")).not.toBeInTheDocument();
  });

  it("renders subTitle when provided", () => {
    render(<EmailInputBlock {...defaultProps} subTitle="Stay updated" />);
    expect(screen.getByText("Stay updated")).toBeInTheDocument();
    expect(screen.getByText("Stay updated").tagName).toBe("H2");
  });

  it("does not render subTitle when not provided", () => {
    const { container } = render(<EmailInputBlock {...defaultProps} />);
    expect(container.querySelector("h2")).not.toBeInTheDocument();
  });

  it("renders emailInputDescription when provided", () => {
    render(
      <EmailInputBlock {...defaultProps} emailInputDescription="Sign up now" />
    );
    expect(screen.getByText("Sign up now")).toBeInTheDocument();
  });

  it("renders caption when provided", () => {
    render(<EmailInputBlock {...defaultProps} caption="No spam" />);
    expect(screen.getByText("No spam")).toBeInTheDocument();
  });

  it("does not render caption when not provided", () => {
    render(<EmailInputBlock {...defaultProps} />);
    expect(screen.queryByText("No spam")).not.toBeInTheDocument();
  });

  it("uses default placeholder text", () => {
    render(<EmailInputBlock {...defaultProps} />);
    expect(
      screen.getByPlaceholderText("Enter your email here")
    ).toBeInTheDocument();
  });

  it("uses custom placeholder text", () => {
    render(<EmailInputBlock {...defaultProps} inputPlaceholder="Your email" />);
    expect(screen.getByPlaceholderText("Your email")).toBeInTheDocument();
  });

  it("calls onSubmit with email on valid submission", () => {
    render(<EmailInputBlock {...defaultProps} />);
    const input = screen.getByPlaceholderText("Enter your email here");
    fireEvent.change(input, { target: { value: "test@example.com" } });
    fireEvent.click(screen.getByText("Sign me up"));
    expect(defaultProps.onSubmit).toHaveBeenCalledWith({
      email: "test@example.com",
    });
  });

  it("clears email after successful submission", () => {
    render(<EmailInputBlock {...defaultProps} />);
    const input = screen.getByPlaceholderText(
      "Enter your email here"
    ) as HTMLInputElement;
    fireEvent.change(input, { target: { value: "test@example.com" } });
    fireEvent.click(screen.getByText("Sign me up"));
    expect(input.value).toBe("");
  });

  it("shows error for invalid email", () => {
    render(<EmailInputBlock {...defaultProps} />);
    const input = screen.getByPlaceholderText("Enter your email here");
    fireEvent.change(input, { target: { value: "invalid" } });
    fireEvent.click(screen.getByText("Sign me up"));
    expect(screen.getByText("Invalid email address")).toBeInTheDocument();
    expect(defaultProps.onSubmit).not.toHaveBeenCalled();
  });

  it("shows required error for empty email", () => {
    render(<EmailInputBlock {...defaultProps} />);
    fireEvent.click(screen.getByText("Sign me up"));
    expect(screen.getByText("Email is required")).toBeInTheDocument();
    expect(defaultProps.onSubmit).not.toHaveBeenCalled();
  });

  it("clears error when user types a valid email after error", () => {
    render(<EmailInputBlock {...defaultProps} />);
    const input = screen.getByPlaceholderText("Enter your email here");
    fireEvent.change(input, { target: { value: "invalid" } });
    fireEvent.click(screen.getByText("Sign me up"));
    expect(screen.getByText("Invalid email address")).toBeInTheDocument();

    fireEvent.change(input, { target: { value: "user@test.com" } });
    expect(
      screen.queryByText("Invalid email address")
    ).not.toBeInTheDocument();
  });

  it("shows success feedback after valid submission", () => {
    render(<EmailInputBlock {...defaultProps} successFeedback="Thanks!" />);
    const input = screen.getByPlaceholderText("Enter your email here");
    fireEvent.change(input, { target: { value: "user@test.com" } });
    fireEvent.click(screen.getByText("Sign me up"));
    expect(screen.getByText("Thanks!")).toBeInTheDocument();
  });

  it("hides success feedback when user types again", () => {
    render(<EmailInputBlock {...defaultProps} successFeedback="Thanks!" />);
    const input = screen.getByPlaceholderText("Enter your email here");
    fireEvent.change(input, { target: { value: "user@test.com" } });
    fireEvent.click(screen.getByText("Sign me up"));
    expect(screen.getByText("Thanks!")).toBeInTheDocument();

    fireEvent.change(input, { target: { value: "x" } });
    expect(screen.queryByText("Thanks!")).not.toBeInTheDocument();
  });

  it("does not show success feedback without successFeedback prop", () => {
    render(<EmailInputBlock {...defaultProps} />);
    const input = screen.getByPlaceholderText("Enter your email here");
    fireEvent.change(input, { target: { value: "user@test.com" } });
    fireEvent.click(screen.getByText("Sign me up"));
    // No success text rendered
    expect(screen.queryByText("Thanks!")).not.toBeInTheDocument();
  });

  it("applies green theme background by default", () => {
    const { container } = render(<EmailInputBlock {...defaultProps} />);
    expect(container.querySelector(".bg-bg-fill-brand")).toBeInTheDocument();
  });

  it("applies blue theme background class", () => {
    const { container } = render(
      <EmailInputBlock {...defaultProps} themeColor="blue" />
    );
    expect(
      container.querySelector(".bg-bg-fill-brand-supporting")
    ).toBeInTheDocument();
  });

  it("applies purple theme background class", () => {
    const { container } = render(
      <EmailInputBlock {...defaultProps} themeColor="purple" />
    );
    expect(
      container.querySelector(".bg-bg-fill-brand-tertiary")
    ).toBeInTheDocument();
  });

  it("applies white outer background class by default", () => {
    const { container } = render(<EmailInputBlock {...defaultProps} />);
    expect(container.querySelector("section")).toHaveClass("bg-bg");
  });

  it("uses white text for dark themes", () => {
    render(
      <EmailInputBlock {...defaultProps} themeColor="blue" title="Blue title" />
    );
    expect(screen.getByText("Blue title").className).toContain("text-white");
  });

  it("uses dark text for the white theme", () => {
    render(
      <EmailInputBlock
        {...defaultProps}
        themeColor="white"
        title="White title"
      />
    );
    expect(screen.getByText("White title").className).toContain("text-text");
  });

  it("uses custom ctaText", () => {
    render(<EmailInputBlock {...defaultProps} ctaText="Subscribe" />);
    expect(screen.getByText("Subscribe")).toBeInTheDocument();
  });
});
