"use client";
import React, { useRef, useState } from "react";
import { Drawer } from "vaul";
import { Star, X, ImagePlus, Loader2, AlertCircle } from "lucide-react";
import { fetchWrapper } from "@/helpers";
import { usePWA } from "@/utlis/usePWA";
import { useIsMobile } from "@/utlis/useIsMobile";

const MAX_IMAGES = 3;
const isEditMode = (mode) => mode === "adminEdit" || mode === "ownEdit";

export default function ReviewForm({ mode = "create", productID, initialData, onClose, onSuccess }) {
	const isPWA = usePWA();
	const isMobile = useIsMobile();
	const isCompact = isPWA || isMobile;

	const [rating, setRating] = useState(initialData?.rating || 0);
	const [hoverRating, setHoverRating] = useState(0);
	const [title, setTitle] = useState(initialData?.title || "");
	const [text, setText] = useState(initialData?.text || "");
	const [imageItems, setImageItems] = useState(
		(initialData?.images || []).map((url) => ({ id: url, url, status: "done" }))
	);
	const [submitting, setSubmitting] = useState(false);
	const [error, setError] = useState("");
	const uploadPromisesRef = useRef({});

	const totalImages = imageItems.length;

	const uploadSingleImage = async (item) => {
		try {
			const fd = new FormData();
			fd.append("images", item.file);
			const res = await fetchWrapper.post("/api/reviews/upload-images", fd);
			const url = res.urls?.[0];
			setImageItems((prev) => prev.map((it) => (it.id === item.id ? { ...it, status: "done", url } : it)));
			return url;
		} catch (err) {
			setImageItems((prev) => prev.map((it) => (it.id === item.id ? { ...it, status: "error" } : it)));
			throw err;
		}
	};

	const handleFilesSelected = (fileList) => {
		const slotsLeft = MAX_IMAGES - totalImages;
		if (slotsLeft <= 0) return;
		const picked = Array.from(fileList).slice(0, slotsLeft);
		const newItems = picked.map((file) => ({
			id: `${file.name}-${file.size}-${Date.now()}-${Math.random()}`,
			file,
			previewUrl: URL.createObjectURL(file),
			status: "uploading",
		}));
		setImageItems((prev) => [...prev, ...newItems]);
		newItems.forEach((item) => {
			uploadPromisesRef.current[item.id] = uploadSingleImage(item);
		});
	};

	const removeImage = (id) => {
		setImageItems((prev) => {
			const item = prev.find((it) => it.id === id);
			if (item?.previewUrl) URL.revokeObjectURL(item.previewUrl);
			return prev.filter((it) => it.id !== id);
		});
		delete uploadPromisesRef.current[id];
	};

	const handleSubmit = async (e) => {
		e.preventDefault();
		setError("");

		if (!rating) return setError("Alege o notă între 1 și 5 stele.");
		if (!text.trim()) return setError("Scrie câteva cuvinte despre produs.");
		if (imageItems.some((it) => it.status === "error")) {
			return setError("O imagine nu a putut fi încărcată. Șterge-o și încearcă din nou.");
		}

		setSubmitting(true);
		try {
			const pendingItems = imageItems.filter((it) => it.status === "uploading");
			const pendingUrls = await Promise.all(pendingItems.map((it) => uploadPromisesRef.current[it.id]));
			const pendingUrlById = new Map(pendingItems.map((it, i) => [it.id, pendingUrls[i]]));

			const images = imageItems
				.map((it) => (it.status === "done" ? it.url : pendingUrlById.get(it.id)))
				.filter(Boolean)
				.slice(0, MAX_IMAGES);

			const payload = { rating, title: title.trim(), text: text.trim(), images };

			if (mode === "adminEdit") {
				await fetchWrapper.put(`/api/admin/reviews/${initialData.id}`, payload);
			} else if (mode === "ownEdit") {
				await fetchWrapper.put(`/api/reviews/${initialData.id}/own`, payload);
			} else {
				await fetchWrapper.post(`/api/reviews/${productID}`, payload);
			}

			onSuccess?.();
			onClose?.();
		} catch (err) {
			setError(typeof err === "string" ? err : "O imagine nu a putut fi încărcată sau a apărut o eroare. Încearcă din nou.");
		} finally {
			setSubmitting(false);
		}
	};

	const formBody = (
		<form className='tf-review-form' onSubmit={handleSubmit}>
			<div className='tf-review-form-field'>
				<label>Nota ta</label>
				<div className='tf-review-star-picker'>
					{[1, 2, 3, 4, 5].map((n) => (
						<button
							type='button'
							key={n}
							onClick={() => setRating(n)}
							onMouseEnter={() => setHoverRating(n)}
							onMouseLeave={() => setHoverRating(0)}
							aria-label={`${n} stele`}>
							<Star size={28} fill={n <= (hoverRating || rating) ? "#ffb800" : "none"} color={n <= (hoverRating || rating) ? "#ffb800" : "#c7c7c7"} />
						</button>
					))}
				</div>
			</div>

			<div className='tf-review-form-field'>
				<label htmlFor='review-title'>Titlu (opțional)</label>
				<input
					id='review-title'
					type='text'
					maxLength={150}
					value={title}
					onChange={(e) => setTitle(e.target.value)}
					placeholder='Ex: Foarte mulțumit/ă'
				/>
			</div>

			<div className='tf-review-form-field'>
				<label htmlFor='review-text'>Părerea ta</label>
				<textarea
					id='review-text'
					rows={4}
					value={text}
					onChange={(e) => setText(e.target.value)}
					placeholder='Ce ți-a plăcut sau ce ar putea fi mai bine?'
				/>
			</div>

			<div className='tf-review-form-field'>
				<label>Fotografii (opțional, max {MAX_IMAGES})</label>
				<div className='tf-review-image-picker'>
					{imageItems.map((item) => (
						<div className={`tf-review-image-thumb ${item.status === "uploading" ? "is-uploading" : ""} ${item.status === "error" ? "is-error" : ""}`} key={item.id}>
							<img src={item.status === "done" ? item.url : item.previewUrl} alt='' />
							{item.status === "uploading" && (
								<div className='tf-review-image-overlay'>
									<Loader2 size={18} className='tf-review-image-spinner' />
								</div>
							)}
							{item.status === "error" && (
								<div className='tf-review-image-overlay tf-review-image-overlay-error'>
									<AlertCircle size={18} />
								</div>
							)}
							<button type='button' onClick={() => removeImage(item.id)} aria-label='Șterge imaginea'>
								<X size={14} />
							</button>
						</div>
					))}
					{totalImages < MAX_IMAGES && (
						<label className='tf-review-image-add'>
							<ImagePlus size={20} />
							<input
								type='file'
								accept='image/png,image/jpeg,image/webp'
								multiple
								hidden
								onChange={(e) => e.target.files && handleFilesSelected(e.target.files)}
							/>
						</label>
					)}
				</div>
			</div>

			{error && <div className='tf-review-form-error'>{error}</div>}

			<button type='submit' className='tf-review-form-submit' disabled={submitting}>
				{submitting ? "Se trimite..." : isEditMode(mode) ? "Salvează modificările" : "Trimite review-ul"}
			</button>
		</form>
	);

	if (isCompact) {
		return (
			<Drawer.Root open onOpenChange={(open) => !open && onClose?.()}>
				<Drawer.Portal>
					<Drawer.Overlay className='tf-review-drawer-overlay' />
					<Drawer.Content className='tf-review-drawer-content'>
						<Drawer.Handle />
						<div className='tf-review-drawer-body'>
							<Drawer.Title className='tf-review-drawer-title'>
								{isEditMode(mode) ? "Editează review-ul" : "Adaugă un review"}
							</Drawer.Title>
							{formBody}
						</div>
					</Drawer.Content>
				</Drawer.Portal>
			</Drawer.Root>
		);
	}

	return (
		<div className='tf-review-modal-overlay' onClick={onClose}>
			<div className='tf-review-modal-content' onClick={(e) => e.stopPropagation()}>
				<div className='tf-review-modal-header'>
					<h4>{isEditMode(mode) ? "Editează review-ul" : "Adaugă un review"}</h4>
					<button type='button' onClick={onClose} aria-label='Închide'>
						<X size={20} />
					</button>
				</div>
				{formBody}
			</div>
		</div>
	);
}
