import React, { useState } from "react";
import { __ } from "@wordpress/i18n";
import { ChevronDown, ChevronRight, ChevronUp, Copy, List, Plus, Trash2 } from "lucide-react";
import ElementRow, { defaultSettingsForType, makeId } from "./ElementRow";

export const makeDefaultStep = (index) => ({
	id: makeId("step"),
	title: `${__("Step", "arraysubs")} ${index + 1}`,
	elements: [],
});

export const makeDefaultElement = (uploadMaxMb) => ({
	id: makeId("el"),
	type: "categories",
	label: "",
	required: false,
	settings: defaultSettingsForType("categories", uploadMaxMb),
});

/**
 * Level-1 collapsible repeater: box steps. Each step nests a level-2
 * repeater of screen elements (products, categories, inputs, uploads).
 */
const StepsBuilder = ({ steps, onChange, uploadMaxMb, confirm, schedule }) => {
	const [collapsedSteps, setCollapsedSteps] = useState({});
	const [collapsedElements, setCollapsedElements] = useState({});

	const updateStep = (stepId, updates) =>
		onChange(steps.map((step) => (step.id === stepId ? { ...step, ...updates } : step)));

	const moveStep = (from, to) => {
		if (to < 0 || to >= steps.length) {
			return;
		}
		const next = [...steps];
		const [moved] = next.splice(from, 1);
		next.splice(to, 0, moved);
		onChange(next);
	};

	const deleteStep = async (step) => {
		try {
			const confirmed = await confirm({
				title: __("Delete Step", "arraysubs"),
				message: __("Delete this step and all of its elements?", "arraysubs"),
				confirmText: __("Delete Step", "arraysubs"),
				cancelText: __("Keep Step", "arraysubs"),
				variant: "danger",
			});
			// useConfirm() RESOLVES false on cancel — it does not reject — so the
			// result has to be checked or "Keep Step" would delete the step too.
			if (!confirmed) {
				return;
			}
			onChange(steps.filter((row) => row.id !== step.id));
		} catch (error) {
			// Dialog threw; leave the step untouched.
		}
	};

	const duplicateStep = (step, index) => {
		const clone = JSON.parse(JSON.stringify(step));
		clone.id = makeId("step");
		clone.title = `${step.title} ${__("(Copy)", "arraysubs")}`;
		clone.elements = clone.elements.map((element) => ({ ...element, id: makeId("el") }));
		const next = [...steps];
		next.splice(index + 1, 0, clone);
		onChange(next);
	};

	return (
		<div className="arraysubs-box-steps-builder">
			{steps.length === 0 && (
				<div className="arraysubs-box-empty">
					{__("No steps yet. Add the first step of your box builder.", "arraysubs")}
				</div>
			)}

			{steps.map((step, stepIndex) => {
				const isCollapsed = !!collapsedSteps[step.id];
				return (
					<div
						key={step.id}
						className={`arraysubs-box-step-row${isCollapsed ? " is-collapsed" : ""}`}
					>
						<div className="arraysubs-box-step-row__header">
							<List size={15} className="arraysubs-box-step-row__icon" />
							<input
								type="text"
								className="arraysubs-box-step-row__title"
								value={step.title}
								onChange={(event) => updateStep(step.id, { title: event.target.value })}
								placeholder={__("Step title", "arraysubs")}
								title={__(
									"Shown to the customer as this screen's heading and as its chip at the top of the box builder.",
									"arraysubs"
								)}
							/>
							<span className="arraysubs-box-step-row__number">#{stepIndex + 1}</span>
							<button
								type="button"
								className="arraysubs-box-step-row__collapse-area"
								onClick={() =>
									setCollapsedSteps((prev) => ({ ...prev, [step.id]: !prev[step.id] }))
								}
								aria-expanded={!isCollapsed}
							>
								<span className="arraysubs-box-step-row__count">
									{step.elements.length === 1
										? __("1 element", "arraysubs")
										: `${step.elements.length} ${__("elements", "arraysubs")}`}
								</span>
							</button>
							<span className="arraysubs-box-step-row__actions">
								<button
									type="button"
									className="button arraysubs-box-icon-btn"
									disabled={stepIndex === 0}
									onClick={() => moveStep(stepIndex, stepIndex - 1)}
									aria-label={__("Move step up", "arraysubs")}
								>
									<ChevronUp size={14} />
								</button>
								<button
									type="button"
									className="button arraysubs-box-icon-btn"
									disabled={stepIndex === steps.length - 1}
									onClick={() => moveStep(stepIndex, stepIndex + 1)}
									aria-label={__("Move step down", "arraysubs")}
								>
									<ChevronDown size={14} />
								</button>
								<button
									type="button"
									className="button arraysubs-box-icon-btn"
									onClick={() => duplicateStep(step, stepIndex)}
									aria-label={__("Duplicate step", "arraysubs")}
								>
									<Copy size={14} />
								</button>
								<button
									type="button"
									className="button arraysubs-box-icon-btn arraysubs-box-icon-btn--danger"
									onClick={() => deleteStep(step)}
									aria-label={__("Delete step", "arraysubs")}
								>
									<Trash2 size={14} />
								</button>
								<button
									type="button"
									className="arraysubs-box-step-row__chevron"
									onClick={() =>
										setCollapsedSteps((prev) => ({ ...prev, [step.id]: !prev[step.id] }))
									}
									aria-expanded={!isCollapsed}
									aria-label={__("Toggle step", "arraysubs")}
								>
									<ChevronRight
										size={16}
										className={`arraysubs-box-collapse-icon${isCollapsed ? "" : " is-expanded"}`}
									/>
								</button>
							</span>
						</div>

						{!isCollapsed && (
							<div className="arraysubs-box-step-row__body">
								{step.elements.map((element, elementIndex) => (
									<ElementRow
										key={element.id}
										element={element}
										index={elementIndex}
										total={step.elements.length}
										collapsed={!!collapsedElements[element.id]}
										uploadMaxMb={uploadMaxMb}
										schedule={schedule}
										onToggleCollapse={() =>
											setCollapsedElements((prev) => ({
												...prev,
												[element.id]: !prev[element.id],
											}))
										}
										onChange={(nextElement) =>
											updateStep(step.id, {
												elements: step.elements.map((row) =>
													row.id === element.id ? nextElement : row
												),
											})
										}
										onDelete={async () => {
											try {
												const confirmed = await confirm({
													title: __("Delete Element", "arraysubs"),
													message: __("Delete this element?", "arraysubs"),
													confirmText: __("Delete", "arraysubs"),
													cancelText: __("Cancel", "arraysubs"),
													variant: "danger",
												});
												// useConfirm() RESOLVES false on cancel — it does not
												// reject — so the result must be checked or Cancel
												// would delete the element too.
												if (!confirmed) {
													return;
												}
												updateStep(step.id, {
													elements: step.elements.filter((row) => row.id !== element.id),
												});
											} catch (error) {
												// Dialog threw; leave the element untouched.
											}
										}}
										onDuplicate={() => {
											const clone = JSON.parse(JSON.stringify(element));
											clone.id = makeId("el");
											const next = [...step.elements];
											next.splice(elementIndex + 1, 0, clone);
											updateStep(step.id, { elements: next });
										}}
										onMove={(from, to) => {
											if (to < 0 || to >= step.elements.length) {
												return;
											}
											const next = [...step.elements];
											const [moved] = next.splice(from, 1);
											next.splice(to, 0, moved);
											updateStep(step.id, { elements: next });
										}}
									/>
								))}

								<button
									type="button"
									className="button arraysubs-box-add-element"
									onClick={() =>
										updateStep(step.id, {
											elements: [...step.elements, makeDefaultElement(uploadMaxMb)],
										})
									}
								>
									<Plus size={14} />
									{__("Add Element", "arraysubs")}
								</button>
							</div>
						)}
					</div>
				);
			})}

			<button
				type="button"
				className="button arraysubs-box-add-step"
				onClick={() => onChange([...steps, makeDefaultStep(steps.length)])}
			>
				<Plus size={14} />
				{__("Add Step", "arraysubs")}
			</button>

			<p className="arraysubs-box-section__desc">
				{__(
					"Steps run in the order shown here. Every step needs a title and at least one element, and the box needs at least one Product or Product Categories element somewhere before it can be saved.",
					"arraysubs"
				)}
			</p>
		</div>
	);
};

export default StepsBuilder;
