import { cn } from "./index3.js";
import { Progress } from "./index16.js";
import { FileTypeIcon } from "./index383.js";
import { useDropZone } from "./index384.js";
import { cva } from "class-variance-authority";
import { AlertCircle, Cloud, Lock, Upload, X } from "lucide-react";
import { forwardRef } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
//#region src/components/molecules/files/FileUpload/FileUpload.tsx
/** biome-ignore-all lint/a11y/useSemanticElements: FileUploadArea uses div with role="button", tabIndex, and full keyboard support for custom drag-drop styling */
var fileUploadAreaVariants = cva("relative flex flex-col items-center justify-center rounded-xl border border-border bg-background transition-[colors,border-color,background-color,box-shadow,transform] duration-200 ease-smooth motion-reduce:transition-none", {
	variants: { state: {
		default: "border-border",
		hover: "border-primary bg-primary/5 shadow-[0_0_0_3px_var(--primary)/0.1] scale-[1.01] motion-reduce:scale-100",
		disabled: "opacity-50 cursor-not-allowed"
	} },
	defaultVariants: { state: "default" }
});
var FileUploadArea = forwardRef(({ className, clickText = "Click to upload", dragText = "or drag and drop", supportingText = "SVG, PNG, JPG or GIF (max. 800x400px)", disabled = false, onFilesSelected, accept, multiple = true, ...props }, ref) => {
	const { isDragging, dropZoneProps, openFilePicker } = useDropZone({
		onFilesSelected,
		accept,
		multiple,
		disabled
	});
	return /* @__PURE__ */ jsx("div", {
		ref,
		className: cn(fileUploadAreaVariants({ state: disabled ? "disabled" : isDragging ? "hover" : "default" }), "group/upload cursor-pointer px-6 py-4", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", className),
		...dropZoneProps,
		onClick: () => openFilePicker(),
		role: "button",
		tabIndex: disabled ? -1 : 0,
		onKeyDown: (e) => {
			if (e.key === "Enter" || e.key === " ") {
				e.preventDefault();
				openFilePicker();
			}
		},
		"aria-disabled": disabled,
		"aria-label": "Upload files by clicking or dragging and dropping",
		...props,
		children: /* @__PURE__ */ jsxs("div", {
			className: "flex flex-col items-center gap-3 w-full",
			children: [/* @__PURE__ */ jsx("div", {
				className: cn("flex size-10 items-center justify-center rounded-lg border border-border bg-card/60 transition-transform duration-200 ease-smooth motion-reduce:transition-none", isDragging && "scale-110"),
				style: { boxShadow: "var(--shadow-button-inset)" },
				children: /* @__PURE__ */ jsx(Upload, { className: cn("size-5 text-secondary-foreground transition-transform duration-200 ease-smooth motion-reduce:transition-none", isDragging && "-translate-y-0.5") })
			}), /* @__PURE__ */ jsxs("div", {
				className: "flex flex-col items-center gap-1 w-full",
				children: [/* @__PURE__ */ jsxs("div", {
					className: "flex items-center justify-center gap-1",
					children: [/* @__PURE__ */ jsx("span", {
						className: "text-sm font-semibold text-secondary-foreground underline underline-offset-2 decoration-transparent transition-[text-decoration-color] duration-200 ease-smooth motion-reduce:transition-none group-hover/upload:decoration-secondary-foreground/40",
						children: clickText
					}), /* @__PURE__ */ jsx("span", {
						className: "text-sm text-muted-foreground",
						children: dragText
					})]
				}), /* @__PURE__ */ jsx("p", {
					className: "text-xs text-muted-foreground text-center",
					children: supportingText
				})]
			})]
		})
	});
});
FileUploadArea.displayName = "FileUploadArea";
var fileUploadItemVariants = cva("relative flex items-start rounded-xl border bg-card transition-colors", {
	variants: { progressType: {
		bar: "gap-1 ps-4 pe-12 py-4 border-border",
		fill: "overflow-hidden min-h-[72px] border-border",
		compact: "border-border overflow-hidden"
	} },
	defaultVariants: { progressType: "fill" }
});
var actionBtnBase = "inline-flex items-center justify-center rounded-full text-muted-foreground hover:text-foreground hover:bg-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring transition-[colors,transform] active:scale-90 motion-reduce:active:scale-100";
function UploadSpinner({ size = 32, className }) {
	const strokeWidth = size <= 20 ? 2.5 : 3;
	const radius = (size - strokeWidth) / 2;
	const circumference = 2 * Math.PI * radius;
	const arcLength = circumference * .25;
	return /* @__PURE__ */ jsxs("svg", {
		width: size,
		height: size,
		viewBox: `0 0 ${size} ${size}`,
		className: cn("animate-spin motion-reduce:animate-none delight-spinner-entrance", className),
		style: { animationDuration: "1s" },
		"aria-hidden": "true",
		children: [/* @__PURE__ */ jsx("circle", {
			cx: size / 2,
			cy: size / 2,
			r: radius,
			fill: "none",
			stroke: "var(--border)",
			strokeWidth,
			strokeLinecap: "round"
		}), /* @__PURE__ */ jsx("circle", {
			cx: size / 2,
			cy: size / 2,
			r: radius,
			fill: "none",
			stroke: "var(--primary)",
			strokeWidth,
			strokeLinecap: "round",
			strokeDasharray: `${arcLength} ${circumference - arcLength}`,
			strokeDashoffset: circumference * .25
		})]
	});
}
function CompactFileItem({ fileName, fileExtension, progress, status, onRemove, onCancel, onRetry }) {
	const isUploading = status === "uploading";
	const isError = status === "error";
	return /* @__PURE__ */ jsxs("div", {
		className: "relative flex flex-col items-center justify-center gap-1.5 size-[100px] p-2",
		children: [
			isUploading && /* @__PURE__ */ jsx("div", {
				className: "absolute inset-0 bg-primary/5 delight-upload-shimmer transition-[width] duration-300 ease-out",
				style: { width: `${progress}%` },
				role: "progressbar",
				"aria-valuenow": progress,
				"aria-valuemin": 0,
				"aria-valuemax": 100,
				"aria-label": `Uploading ${fileName}: ${progress}%`
			}),
			/* @__PURE__ */ jsxs("div", {
				className: "absolute top-1 end-1 z-10",
				children: [isUploading && onCancel && /* @__PURE__ */ jsx("button", {
					type: "button",
					onClick: onCancel,
					"aria-label": `Cancel upload of ${fileName}`,
					className: `size-5 bg-accent/80 ${actionBtnBase}`,
					children: /* @__PURE__ */ jsx(X, { className: "size-3" })
				}), (status === "complete" || isError) && onRemove && /* @__PURE__ */ jsx("button", {
					type: "button",
					onClick: onRemove,
					"aria-label": `Remove ${fileName}`,
					className: `size-5 bg-accent/80 ${actionBtnBase}`,
					children: /* @__PURE__ */ jsx(X, { className: "size-3" })
				})]
			}),
			/* @__PURE__ */ jsx("div", {
				className: "relative",
				children: isUploading ? /* @__PURE__ */ jsx(UploadSpinner, { size: 16 }) : isError ? /* @__PURE__ */ jsx(AlertCircle, { className: "size-4 text-destructive delight-shake" }) : /* @__PURE__ */ jsx(FileTypeIcon, {
					extension: fileExtension,
					size: "sm"
				})
			}),
			/* @__PURE__ */ jsx("span", {
				className: "relative text-[10px] leading-tight text-muted-foreground text-center truncate max-w-[80px] px-1",
				children: fileName
			}),
			isError && onRetry && /* @__PURE__ */ jsx("button", {
				type: "button",
				onClick: onRetry,
				className: "relative text-[10px] text-destructive underline hover:text-destructive/80 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
				children: "Retry"
			})
		]
	});
}
function FillFileItem({ fileName, fileSize, fileExtension, progress, status, onRemove, onCancel, onRetry, titleAddon, actions }) {
	const isUploading = status === "uploading";
	const isError = status === "error";
	const isComplete = status === "complete" || progress >= 100;
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [
		isUploading && /* @__PURE__ */ jsx("div", {
			className: "absolute inset-0 bg-primary/5 rounded-xl delight-upload-shimmer transition-[width] duration-300 ease-out",
			style: { width: `${progress}%` },
			role: "progressbar",
			"aria-valuenow": progress,
			"aria-valuemin": 0,
			"aria-valuemax": 100,
			"aria-label": `Uploading ${fileName}: ${progress}%`
		}),
		isComplete && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-muted delight-upload-complete animate-in fade-in-0 duration-300 motion-reduce:animate-none" }),
		/* @__PURE__ */ jsxs("div", {
			className: "relative flex items-center gap-3 h-[72px] w-full px-3",
			children: [
				/* @__PURE__ */ jsx(FileTypeIcon, {
					extension: fileExtension,
					size: "lg",
					className: "shrink-0"
				}),
				/* @__PURE__ */ jsxs("div", {
					className: "flex-1 min-w-0 flex flex-col gap-0.5",
					children: [/* @__PURE__ */ jsxs("div", {
						className: "flex items-center gap-2 min-w-0",
						children: [/* @__PURE__ */ jsx("span", {
							className: "text-sm font-medium text-foreground truncate",
							children: fileName
						}), titleAddon]
					}), /* @__PURE__ */ jsx("span", {
						className: "text-xs text-muted-foreground",
						children: isError ? /* @__PURE__ */ jsxs("span", {
							className: "text-destructive flex items-center gap-1 delight-shake",
							children: [
								/* @__PURE__ */ jsx(AlertCircle, { className: "size-3 shrink-0" }),
								"Upload failed",
								onRetry && /* @__PURE__ */ jsxs(Fragment$1, { children: [" · ", /* @__PURE__ */ jsx("button", {
									type: "button",
									onClick: onRetry,
									className: "underline hover:text-destructive/80 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
									children: "Retry"
								})] })
							]
						}) : isUploading ? `${fileSize ?? ""} \u00B7 ${progress}%` : fileSize
					})]
				}),
				/* @__PURE__ */ jsx("div", {
					className: "shrink-0 flex items-center gap-2",
					children: actions ? /* @__PURE__ */ jsx("span", {
						"data-slot": "actions",
						children: actions
					}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
						isUploading && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(UploadSpinner, { size: 32 }), onCancel && /* @__PURE__ */ jsx("button", {
							type: "button",
							onClick: onCancel,
							"aria-label": `Cancel upload of ${fileName}`,
							className: `size-6 ${actionBtnBase}`,
							children: /* @__PURE__ */ jsx(X, { className: "size-4" })
						})] }),
						(isComplete || isError) && onRemove && /* @__PURE__ */ jsx("button", {
							type: "button",
							onClick: onRemove,
							"aria-label": `Remove ${fileName}`,
							className: `size-6 ${actionBtnBase}`,
							children: /* @__PURE__ */ jsx(X, { className: "size-4" })
						}),
						status === "disabled" && /* @__PURE__ */ jsx(Lock, {
							className: "size-4 text-muted-foreground",
							"aria-label": "File locked"
						}),
						status === "cloud" && /* @__PURE__ */ jsx(Cloud, {
							className: "size-4 text-muted-foreground",
							"aria-label": "Cloud file"
						})
					] })
				})
			]
		})
	] });
}
var FileUploadItem = forwardRef(({ className, fileName, fileSize, fileExtension, progress: rawProgress = 0, status = "uploading", progressType = "fill", titleAddon, onRemove, onCancel, onRetry, actions, ...props }, ref) => {
	const progress = Math.min(100, Math.max(0, rawProgress));
	const isError = status === "error";
	const isComplete = status === "complete" || progress >= 100;
	if (progressType === "compact") return /* @__PURE__ */ jsx("div", {
		ref,
		"data-slot": "file-upload-item",
		"data-status": status,
		className: cn(fileUploadItemVariants({ progressType }), isError && "border-destructive/50", className),
		...props,
		children: /* @__PURE__ */ jsx(CompactFileItem, {
			fileName,
			fileExtension,
			progress,
			status,
			onRemove,
			onCancel,
			onRetry
		})
	});
	if (progressType === "fill") return /* @__PURE__ */ jsx("div", {
		ref,
		"data-slot": "file-upload-item",
		"data-status": status,
		className: cn(fileUploadItemVariants({ progressType }), isError && "border-destructive/50", className),
		...props,
		children: /* @__PURE__ */ jsx(FillFileItem, {
			fileName,
			fileSize,
			fileExtension,
			progress,
			status,
			onRemove,
			onCancel,
			onRetry,
			titleAddon,
			actions
		})
	});
	return /* @__PURE__ */ jsxs("div", {
		ref,
		"data-slot": "file-upload-item",
		"data-status": status,
		className: cn(fileUploadItemVariants({ progressType }), isError && "border-destructive/50", className),
		...props,
		children: [/* @__PURE__ */ jsxs("div", {
			className: "flex flex-1 gap-3 items-start min-w-0",
			children: [/* @__PURE__ */ jsx(FileTypeIcon, {
				extension: fileExtension,
				size: "md"
			}), /* @__PURE__ */ jsxs("div", {
				className: "flex flex-1 flex-col gap-1 min-w-0",
				children: [/* @__PURE__ */ jsxs("div", {
					className: "flex flex-col w-full",
					children: [/* @__PURE__ */ jsxs("div", {
						className: "flex items-center gap-2 min-w-0",
						children: [/* @__PURE__ */ jsx("p", {
							className: "text-sm font-medium text-secondary-foreground truncate",
							children: fileName
						}), titleAddon]
					}), /* @__PURE__ */ jsx("p", {
						className: "text-sm text-muted-foreground",
						children: isError ? /* @__PURE__ */ jsxs("span", {
							className: "text-destructive flex items-center gap-1 delight-shake",
							children: [
								/* @__PURE__ */ jsx(AlertCircle, { className: "size-3 shrink-0" }),
								"Upload failed",
								onRetry && /* @__PURE__ */ jsxs(Fragment$1, { children: [" · ", /* @__PURE__ */ jsx("button", {
									type: "button",
									onClick: onRetry,
									className: "underline hover:text-destructive/80 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
									children: "Retry"
								})] })
							]
						}) : fileSize
					})]
				}), status === "uploading" && !isComplete && /* @__PURE__ */ jsx(Progress, {
					value: progress,
					size: "md",
					className: "w-full"
				})]
			})]
		}), /* @__PURE__ */ jsx("div", {
			className: "absolute top-2 end-4 flex items-center gap-2",
			children: actions ? /* @__PURE__ */ jsx("span", {
				"data-slot": "actions",
				children: actions
			}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
				status === "uploading" && onCancel && /* @__PURE__ */ jsx("button", {
					type: "button",
					onClick: onCancel,
					"aria-label": `Cancel upload of ${fileName}`,
					className: `size-6 ${actionBtnBase}`,
					children: /* @__PURE__ */ jsx(X, { className: "size-4" })
				}),
				(isComplete || isError) && onRemove && /* @__PURE__ */ jsx("button", {
					type: "button",
					onClick: onRemove,
					"aria-label": `Remove ${fileName}`,
					className: `size-6 ${actionBtnBase}`,
					children: /* @__PURE__ */ jsx(X, { className: "size-4" })
				}),
				status === "disabled" && /* @__PURE__ */ jsx(Lock, {
					className: "size-4 text-muted-foreground",
					"aria-label": "File locked"
				}),
				status === "cloud" && /* @__PURE__ */ jsx(Cloud, {
					className: "size-4 text-muted-foreground",
					"aria-label": "Cloud file"
				})
			] })
		})]
	});
});
FileUploadItem.displayName = "FileUploadItem";
var FileUpload = forwardRef(({ className, files = [], progressType = "fill", areaProps, onFilesSelected, onFileRemove, onFileCancel, ...props }, ref) => {
	return /* @__PURE__ */ jsxs("div", {
		ref,
		className: cn("flex flex-col gap-4 w-full", className),
		...props,
		children: [/* @__PURE__ */ jsx(FileUploadArea, {
			onFilesSelected,
			...areaProps
		}), files.length > 0 && /* @__PURE__ */ jsx("div", {
			className: "flex flex-col gap-3",
			children: files.map((file, index) => /* @__PURE__ */ jsx(FileUploadItem, {
				fileName: file.name,
				fileSize: file.size,
				fileExtension: file.extension,
				progress: file.progress,
				status: file.status,
				progressType,
				onRemove: () => onFileRemove?.(file.id),
				onCancel: () => onFileCancel?.(file.id),
				className: "delight-stagger",
				style: { "--delight-delay": `${index * 60}ms` }
			}, file.id))
		})]
	});
});
FileUpload.displayName = "FileUpload";
//#endregion
export { FileUpload, FileUploadArea, FileUploadItem, fileUploadAreaVariants, fileUploadItemVariants };

//# sourceMappingURL=index385.js.map