import { render, screen, fireEvent } from "@testing-library/react";
import { SignInSteps } from "./sign-in-steps";
import { vi } from "vitest";

import { SignInStatus } from "../../types/sign-in-types";

const defaultProps = {
	signInStatus: "not-started" as SignInStatus,
	signInError: "",
	onSignIn: vi.fn(),
	onCancel: vi.fn(),
};

describe("SignInSteps", () => {
	beforeEach(() => {
		vi.clearAllMocks();
	});

	it("renders welcome message and sign in button when not started", () => {
		render(<SignInSteps {...defaultProps} signInStatus="not-started" />);

		expect(
			screen.getByText(/An agentic IDE that helps you do your best work/)
		).toBeInTheDocument();
		expect(screen.getByRole("button", { name: /Sign in/ })).toBeInTheDocument();
	});

	it("shows pending message and cancel button during sign in", () => {
		render(<SignInSteps {...defaultProps} signInStatus="pending" portalUrl="https://app.kiro.dev/signin?state=123" />);

		expect(
			screen.getByText(/We will take you to your default web browser/)
		).toBeInTheDocument();
		expect(screen.getByRole("button", { name: /Cancel/ })).toBeInTheDocument();
		expect(
			screen.queryByRole("button", { name: /Sign in/ })
		).not.toBeInTheDocument();
	});

	it("shows portal URL when provided during pending state", () => {
		const portalUrl = "https://app.kiro.dev/signin?state=123";
		render(<SignInSteps {...defaultProps} signInStatus="pending" portalUrl={portalUrl} />);

		expect(screen.getByText(portalUrl)).toBeInTheDocument();
		expect(screen.getByText(/Or open this link in your browser/)).toBeInTheDocument();
	});

	it("shows success message when signed in", () => {
		render(<SignInSteps {...defaultProps} signInStatus="success" />);

		expect(screen.getByText(/You are signed in!/)).toBeInTheDocument();
		expect(
			screen.queryByRole("button", { name: /Sign in/ })
		).not.toBeInTheDocument();
	});

	it("shows error message and sign in button when error occurs", () => {
		render(<SignInSteps {...defaultProps} signInStatus="error" signInError="Authentication failed" />);

		expect(screen.getByText(/Authentication failed/)).toBeInTheDocument();
		expect(screen.getByRole("button", { name: /Sign in/ })).toBeInTheDocument();
	});

	it("shows default error message when error occurs without message", () => {
		render(<SignInSteps {...defaultProps} signInStatus="error" signInError="" />);

		expect(
			screen.getByText(/There was an error signing you in/)
		).toBeInTheDocument();
	});

	it("calls onSignIn with portal auth method when sign in button is clicked", () => {
		const mockOnSignIn = vi.fn();
		render(<SignInSteps {...defaultProps} signInStatus="not-started" onSignIn={mockOnSignIn} />);

		fireEvent.click(screen.getByRole("button", { name: /Sign in/ }));

		expect(mockOnSignIn).toHaveBeenCalledWith({ authMethod: "portal" });
	});

	it("calls onCancel when cancel button is clicked", () => {
		const mockOnCancel = vi.fn();
		render(<SignInSteps {...defaultProps} signInStatus="pending" portalUrl="https://app.kiro.dev/signin" onCancel={mockOnCancel} />);

		fireEvent.click(screen.getByRole("button", { name: /Cancel/ }));

		expect(mockOnCancel).toHaveBeenCalled();
	});

	it("shows legal links", () => {
		render(<SignInSteps {...defaultProps} signInStatus="not-started" />);

		expect(screen.getByText(/AWS Customer Agreement/)).toBeInTheDocument();
		expect(screen.getByText(/Service Terms/)).toBeInTheDocument();
		expect(screen.getByText(/Privacy Notice/)).toBeInTheDocument();
	});
});
