import { useZoom } from "../zoomPlugin/ZoomContext.js";
import { useRedactContext } from "./RedactContext.js";
import { normRect } from "./useRedactTool.js";

/**
 * Canvas-area overlay for the redact tool.
 * Uses an SVG layer over the image for drawing; blur preview uses SVG feGaussianBlur
 * so the live preview matches the final applied output.
 */
export function RedactOverlay() {
	let {
		imageUrl,
		rects,
		drawing,
		displaySize,
		handleImageLoad,
		startDrawing,
		updateDrawing,
		finishDrawing,
		deleteRect,
	} = useRedactContext();

	let { zoom } = useZoom();
	let inProgress = drawing ? normRect(drawing) : null;

	function onPointerDown(e: React.PointerEvent<SVGSVGElement>) {
		e.currentTarget.setPointerCapture(e.pointerId);
		let b = e.currentTarget.getBoundingClientRect();
		startDrawing((e.clientX - b.left) / zoom, (e.clientY - b.top) / zoom);
	}

	function onPointerMove(e: React.PointerEvent<SVGSVGElement>) {
		if (!(e.buttons & 1)) return;
		let b = e.currentTarget.getBoundingClientRect();
		updateDrawing((e.clientX - b.left) / zoom, (e.clientY - b.top) / zoom);
	}

	return (
		<div className="redact-root">
			<div className="redact-inner">
				<img src={imageUrl} alt="" className="redact-image" onLoad={handleImageLoad} draggable={false} />

				{displaySize.width > 0 && (
					<svg
						className="redact-svg"
						width={displaySize.width}
						height={displaySize.height}
						onPointerDown={onPointerDown}
						onPointerMove={onPointerMove}
						onPointerUp={finishDrawing}
					>
						<defs>
							<filter id="redact-blur" x="-50%" y="-50%" width="200%" height="200%">
								<feGaussianBlur stdDeviation="20" />
							</filter>
							{rects.map((_, i) => (
								<clipPath key={i} id={`redact-clip-${i}`}>
									<rect x={rects[i].x} y={rects[i].y} width={rects[i].w} height={rects[i].h} />
								</clipPath>
							))}
							{inProgress && (
								<clipPath id="redact-clip-inprogress">
									<rect x={inProgress.x} y={inProgress.y} width={inProgress.w} height={inProgress.h} />
								</clipPath>
							)}
						</defs>

						{/* Blur each confirmed rect using the real image, clipped to the rect */}
						{rects.map((r, i) => (
							<g key={i}>
								<image
									href={imageUrl}
									width={displaySize.width}
									height={displaySize.height}
									filter="url(#redact-blur)"
									clipPath={`url(#redact-clip-${i})`}
									style={{ pointerEvents: "none" }}
								/>
								{/* Semi-opaque overlay to prevent text from being readable through the blur */}
								<rect
									x={r.x}
									y={r.y}
									width={r.w}
									height={r.h}
									fill="rgba(128,128,128,0.85)"
									style={{ pointerEvents: "none" }}
								/>
								{/* Dashed border + invisible hit area for deletion */}
								<rect
									x={r.x}
									y={r.y}
									width={r.w}
									height={r.h}
									fill="transparent"
									stroke="rgba(255,255,255,0.6)"
									strokeWidth={1.5}
									strokeDasharray="5 3"
									style={{ cursor: "pointer" }}
									onClick={(e) => {
										e.stopPropagation();
										deleteRect(i);
									}}
								/>
							</g>
						))}

						{/* In-progress rect */}
						{inProgress && (
							<>
								<image
									href={imageUrl}
									width={displaySize.width}
									height={displaySize.height}
									filter="url(#redact-blur)"
									clipPath="url(#redact-clip-inprogress)"
									style={{ pointerEvents: "none" }}
								/>
								<rect
									x={inProgress.x}
									y={inProgress.y}
									width={inProgress.w}
									height={inProgress.h}
									fill="rgba(128,128,128,0.85)"
									style={{ pointerEvents: "none" }}
								/>
								<rect
									x={inProgress.x}
									y={inProgress.y}
									width={inProgress.w}
									height={inProgress.h}
									fill="transparent"
									stroke="rgba(255,255,255,0.6)"
									strokeWidth={1.5}
									strokeDasharray="5 3"
									style={{ pointerEvents: "none" }}
								/>
							</>
						)}
					</svg>
				)}
			</div>
		</div>
	);
}
