import CropStep from "@ax/components/ImageDragAndDrop/CropStep";
import { parseTheme } from "@ax/helpers";
import globalTheme from "@ax/themes/theme.json";

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

afterEach(cleanup);

const renderCropStep = (props = {}) =>
	render(
		<ThemeProvider theme={parseTheme(globalTheme)}>
			<CropStep imageSrc="data:image/jpeg;base64,abc" onConfirm={jest.fn()} onCancel={jest.fn()} {...props} />
		</ThemeProvider>,
	);

describe("CropStep rendering", () => {
	it("should render the cropper", () => {
		renderCropStep();
		expect(screen.getByTestId("cropper-mock")).toBeTruthy();
	});

	it("should render zoom controls", () => {
		renderCropStep();
		expect(screen.getByLabelText("Zoom in")).toBeTruthy();
		expect(screen.getByLabelText("Zoom out")).toBeTruthy();
		expect(screen.getByLabelText("Zoom")).toBeTruthy();
	});

	it("should render Done and Upload new image buttons", () => {
		renderCropStep();
		expect(screen.getByText("Done")).toBeTruthy();
		expect(screen.getByText("Upload new image")).toBeTruthy();
	});

	it("should render zoom slider with correct range and step", () => {
		renderCropStep();
		const slider = screen.getByLabelText("Zoom") as HTMLInputElement;
		expect(slider).toBeTruthy();
		expect(slider.min).toBe("1");
		expect(slider.max).toBe("3");
		expect(slider.step).toBe("0.1");
		expect(slider.value).toBe("1");
	});
});

describe("CropStep events", () => {
	it("should call onConfirm with cropped area when Done is clicked", () => {
		const onConfirm = jest.fn();
		renderCropStep({ onConfirm });
		fireEvent.click(screen.getByText("Done"));
		expect(onConfirm).toHaveBeenCalledWith({ x: 0, y: 0, width: 100, height: 100 });
	});

	it("should call onCancel when Upload new image is clicked", () => {
		const onCancel = jest.fn();
		renderCropStep({ onCancel });
		fireEvent.click(screen.getByText("Upload new image"));
		expect(onCancel).toHaveBeenCalledTimes(1);
	});

	it("should update zoom value when slider changes", () => {
		renderCropStep();
		const slider = screen.getByLabelText("Zoom") as HTMLInputElement;
		fireEvent.change(slider, { target: { value: "2" } });
		expect(slider.value).toBe("2");
	});

	it("should increase zoom when zoom in button is clicked", () => {
		renderCropStep();
		const slider = screen.getByLabelText("Zoom") as HTMLInputElement;
		fireEvent.click(screen.getByLabelText("Zoom in"));
		expect(slider.value).toBe("1.1");
	});

	it("should decrease zoom when zoom out button is clicked", () => {
		renderCropStep();
		const slider = screen.getByLabelText("Zoom") as HTMLInputElement;
		expect(slider.value).toBe("1");
		fireEvent.click(screen.getByLabelText("Zoom out"));
		// Zoom can't go below MIN_ZOOM (1), so it should stay at 1
		expect(slider.value).toBe("1");
	});
});
