import React, { useRef, useState, useCallback } from "react";
import { Button } from "@/components/ui/button";
import {
    Upload, Camera, Trash2, ImageIcon, Star, StarOff, ZoomIn, X,
    Sparkles, RotateCw, Plus,
} from "lucide-react";
import { toast } from "sonner";

/**
 * MultiImageUploader — Up to 10 images per item.
 * - Big cover preview on top, thumbnail strip below (with "+" tile).
 * - Add / Replace / Remove / Drag-reorder / Set Cover / Zoom / Rotate
 * - Auto-compress large images via canvas (≤ ~700px wide, JPEG q=0.82) for offline-safe storage.
 * - Stores all images as base64 data-URLs (same as existing photo_url) — Dexie / IndexedDB compatible.
 *
 * Props:
 *  - coverImage:  string (data URL)
 *  - images:      string[] (data URLs)
 *  - onChange({ cover_image, images })
 *  - maxImages:   default 10
 *  - maxSizeMB:   per source file size cap before compression (default 8)
 *  - testidPrefix
 *  - onAiSuggest: optional () => Promise — when provided, shows "AI Suggest from Image"
 *  - aiBusy:      boolean
 */
export function MultiImageUploader({
    coverImage = "",
    images = [],
    onChange,
    maxImages = 10,
    maxSizeMB = 8,
    testidPrefix = "item-images",
    onAiSuggest,
    aiBusy = false,
}) {
    // Normalise: ensure cover is in images[0]. If only legacy cover present, lift it.
    const list = React.useMemo(() => {
        const arr = Array.isArray(images) ? images.filter(Boolean) : [];
        if (coverImage && !arr.includes(coverImage)) return [coverImage, ...arr];
        if (coverImage && arr[0] !== coverImage) {
            // move cover to front
            return [coverImage, ...arr.filter((x) => x !== coverImage)];
        }
        return arr;
    }, [coverImage, images]);

    const fileRef = useRef(null);
    const cameraRef = useRef(null);
    const [dragOver, setDragOver] = useState(false);
    const [zoomSrc, setZoomSrc] = useState("");
    const [draggingIdx, setDraggingIdx] = useState(null);
    const [dropTargetIdx, setDropTargetIdx] = useState(null);

    const emit = useCallback((next) => {
        const safe = next.slice(0, maxImages);
        onChange?.({ cover_image: safe[0] || "", images: safe });
    }, [onChange, maxImages]);

    /** Canvas-based compression: scale to max 800px wide, JPEG q=0.82. */
    const compressDataUrl = (rawDataUrl, maxW = 800, quality = 0.82) =>
        new Promise((resolve) => {
            const img = new Image();
            img.onload = () => {
                try {
                    const ratio = img.width > maxW ? maxW / img.width : 1;
                    const w = Math.round(img.width * ratio);
                    const h = Math.round(img.height * ratio);
                    const canvas = document.createElement("canvas");
                    canvas.width = w; canvas.height = h;
                    const ctx = canvas.getContext("2d");
                    ctx.fillStyle = "#fff"; // matte white bg for transparent PNGs
                    ctx.fillRect(0, 0, w, h);
                    ctx.drawImage(img, 0, 0, w, h);
                    resolve(canvas.toDataURL("image/jpeg", quality));
                } catch {
                    resolve(rawDataUrl);
                }
            };
            img.onerror = () => resolve(rawDataUrl);
            img.src = rawDataUrl;
        });

    const handleFiles = async (files) => {
        if (!files || !files.length) return;
        const remaining = maxImages - list.length;
        if (remaining <= 0) {
            toast.error(`Maximum ${maxImages} images. Remove one first.`);
            return;
        }
        const chosen = Array.from(files).slice(0, remaining);
        const valid = ["image/png", "image/jpeg", "image/webp"];
        const accepted = [];
        for (const f of chosen) {
            if (!valid.includes(f.type)) {
                toast.error(`Skipping ${f.name}: only JPG/PNG/WEBP allowed`);
                continue;
            }
            if (f.size > maxSizeMB * 1024 * 1024) {
                toast.error(`Skipping ${f.name}: > ${maxSizeMB} MB`);
                continue;
            }
            accepted.push(f);
        }
        if (!accepted.length) return;

        const reads = await Promise.all(accepted.map((f) => new Promise((resolve) => {
            const r = new FileReader();
            r.onload = () => resolve(String(r.result || ""));
            r.onerror = () => resolve("");
            r.readAsDataURL(f);
        })));
        const compressed = [];
        for (const raw of reads) {
            if (!raw) continue;
            // De-dupe to prevent duplicate uploads
            if (list.includes(raw) || compressed.includes(raw)) continue;
            const small = await compressDataUrl(raw);
            // Final de-dupe after compression
            if (!list.includes(small) && !compressed.includes(small)) compressed.push(small);
        }
        if (!compressed.length) {
            toast.message("No new images added (duplicates skipped)");
            return;
        }
        emit([...list, ...compressed]);
        toast.success(`${compressed.length} image${compressed.length === 1 ? "" : "s"} added`);
    };

    const removeAt = (idx) => {
        const next = list.filter((_, i) => i !== idx);
        emit(next);
    };

    const setCover = (idx) => {
        if (idx === 0) return;
        const next = [list[idx], ...list.filter((_, i) => i !== idx)];
        emit(next);
        toast.success("Cover image updated");
    };

    const rotateAt = async (idx) => {
        const src = list[idx];
        const rotated = await new Promise((resolve) => {
            const img = new Image();
            img.onload = () => {
                try {
                    const canvas = document.createElement("canvas");
                    canvas.width = img.height; canvas.height = img.width;
                    const ctx = canvas.getContext("2d");
                    ctx.translate(canvas.width / 2, canvas.height / 2);
                    ctx.rotate(Math.PI / 2);
                    ctx.drawImage(img, -img.width / 2, -img.height / 2);
                    resolve(canvas.toDataURL("image/jpeg", 0.85));
                } catch { resolve(src); }
            };
            img.onerror = () => resolve(src);
            img.src = src;
        });
        const next = [...list];
        next[idx] = rotated;
        emit(next);
    };

    const onDropZone = (e) => {
        e.preventDefault();
        setDragOver(false);
        // Only treat as file-drop if there are actual files (not internal reorder)
        if (e.dataTransfer?.files?.length) handleFiles(e.dataTransfer.files);
    };

    // Internal reorder drag-and-drop
    const onTileDragStart = (idx, e) => {
        setDraggingIdx(idx);
        e.dataTransfer.effectAllowed = "move";
        // marker so we don't treat as file drop
        try { e.dataTransfer.setData("text/x-rbs-img-idx", String(idx)); } catch { /* noop */ }
    };
    const onTileDragOver = (idx, e) => {
        e.preventDefault();
        setDropTargetIdx(idx);
    };
    const onTileDrop = (idx, e) => {
        e.preventDefault();
        e.stopPropagation();
        if (draggingIdx == null || draggingIdx === idx) {
            setDraggingIdx(null); setDropTargetIdx(null); return;
        }
        const next = [...list];
        const [moved] = next.splice(draggingIdx, 1);
        next.splice(idx, 0, moved);
        emit(next);
        setDraggingIdx(null);
        setDropTargetIdx(null);
    };
    const onTileDragEnd = () => { setDraggingIdx(null); setDropTargetIdx(null); };

    const cover = list[0] || "";
    const count = list.length;
    const canAdd = count < maxImages;

    return (
        <div className="space-y-2" data-testid={`${testidPrefix}-uploader`}>
            {/* Header */}
            <div className="flex items-center justify-between">
                <span className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5">
                    <ImageIcon className="h-3.5 w-3.5" /> Product Images
                    <span className="ml-1 px-1.5 py-0.5 rounded bg-primary/10 text-primary text-[10px] font-bold tracking-wider" data-testid={`${testidPrefix}-count`}>
                        {count}/{maxImages}
                    </span>
                </span>
                <span className="text-[10px] text-muted-foreground">JPG · PNG · WEBP · drag to reorder</span>
            </div>

            {/* Main cover preview + dropzone */}
            <div className="grid grid-cols-12 gap-3 items-stretch">
                <div className="col-span-12 sm:col-span-5" data-testid={`${testidPrefix}-cover-container`}>
                    <div
                        className="relative aspect-square w-full rounded-lg border-2 border-dashed border-border bg-white dark:bg-muted/20 flex items-center justify-center overflow-hidden group"
                    >
                        {cover ? (
                            <>
                                <img
                                    src={cover}
                                    alt="Cover"
                                    className="w-full h-full object-contain"
                                    data-testid={`${testidPrefix}-cover-preview`}
                                />
                                <button
                                    type="button"
                                    onClick={() => setZoomSrc(cover)}
                                    className="absolute top-2 right-2 h-8 w-8 rounded-full bg-black/60 text-white hover:bg-black/80 flex items-center justify-center opacity-0 group-hover:opacity-100 transition"
                                    title="Zoom"
                                    data-testid={`${testidPrefix}-cover-zoom`}
                                >
                                    <ZoomIn className="h-4 w-4" />
                                </button>
                                <div className="absolute bottom-2 left-2 flex items-center gap-1 text-[10px] font-semibold uppercase tracking-wider bg-amber-500/95 text-white px-2 py-0.5 rounded-full">
                                    <Star className="h-3 w-3" /> Cover
                                </div>
                            </>
                        ) : (
                            <div className="text-center text-muted-foreground p-3">
                                <ImageIcon className="h-8 w-8 mx-auto opacity-50" />
                                <div className="text-[10px] mt-1 uppercase tracking-wider">No image</div>
                                <div className="text-[10px] text-muted-foreground mt-0.5">Add up to {maxImages} images</div>
                            </div>
                        )}
                    </div>
                </div>

                <div className="col-span-12 sm:col-span-7 flex flex-col gap-2">
                    <button
                        type="button"
                        onClick={() => canAdd && fileRef.current?.click()}
                        onDragOver={(e) => { e.preventDefault(); if (canAdd) setDragOver(true); }}
                        onDragLeave={() => setDragOver(false)}
                        onDrop={onDropZone}
                        disabled={!canAdd}
                        data-testid={`${testidPrefix}-dropzone`}
                        className={`flex-1 min-h-[120px] flex flex-col items-center justify-center rounded-lg border-2 border-dashed transition-all p-3 text-center cursor-pointer
                            ${!canAdd
                                ? "opacity-50 cursor-not-allowed border-border bg-muted/10"
                                : dragOver
                                    ? "border-primary bg-primary/5"
                                    : "border-border bg-muted/20 hover:border-primary/40 hover:bg-primary/[.03]"}
                        `}
                    >
                        <Upload className={`h-5 w-5 mb-1 ${dragOver ? "text-primary" : "text-muted-foreground"}`} />
                        <div className="text-sm font-semibold">
                            {canAdd ? (count ? "Add more images" : "Click or drag images") : `Max ${maxImages} reached`}
                        </div>
                        <div className="text-[10px] text-muted-foreground mt-0.5">Up to {maxImages - count} more · multi-select supported</div>
                    </button>

                    <div className="flex gap-2 flex-wrap">
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={() => fileRef.current?.click()}
                            disabled={!canAdd}
                            className="flex-1 min-w-[110px]"
                            data-testid={`${testidPrefix}-add-btn`}
                        >
                            <Plus className="h-3.5 w-3.5 mr-1.5" /> Add Image
                        </Button>
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={() => cameraRef.current?.click()}
                            disabled={!canAdd}
                            className="flex-1 min-w-[110px]"
                            data-testid={`${testidPrefix}-camera-btn`}
                        >
                            <Camera className="h-3.5 w-3.5 mr-1.5" /> Take Photo
                        </Button>
                        {onAiSuggest && cover && (
                            <Button
                                type="button"
                                variant="outline"
                                size="sm"
                                onClick={onAiSuggest}
                                disabled={aiBusy}
                                className="flex-1 min-w-[140px] border-amber-400/60 text-amber-700 dark:text-amber-400 hover:bg-amber-50 dark:hover:bg-amber-950/30"
                                data-testid={`${testidPrefix}-ai-suggest-btn`}
                                title="Use AI to suggest item name, HSN, GST, brand, category, description from this image"
                            >
                                <Sparkles className={`h-3.5 w-3.5 mr-1.5 ${aiBusy ? "animate-spin" : ""}`} />
                                {aiBusy ? "Analysing…" : "AI Suggest"}
                            </Button>
                        )}
                    </div>
                </div>
            </div>

            {/* Thumbnail strip */}
            {count > 0 && (
                <div
                    className="flex flex-wrap gap-2 pt-2 border-t border-border/50"
                    data-testid={`${testidPrefix}-strip`}
                >
                    {list.map((src, idx) => {
                        const isCover = idx === 0;
                        const isDropTarget = dropTargetIdx === idx && draggingIdx !== null && draggingIdx !== idx;
                        return (
                            <div
                                key={`${idx}-${src.slice(-12)}`}
                                draggable
                                onDragStart={(e) => onTileDragStart(idx, e)}
                                onDragOver={(e) => onTileDragOver(idx, e)}
                                onDrop={(e) => onTileDrop(idx, e)}
                                onDragEnd={onTileDragEnd}
                                className={`relative h-20 w-20 rounded-md overflow-hidden border-2 group cursor-move transition
                                    ${isCover ? "border-amber-400 ring-2 ring-amber-300/50" : "border-border"}
                                    ${isDropTarget ? "scale-105 ring-2 ring-primary" : ""}
                                    ${draggingIdx === idx ? "opacity-40" : "opacity-100"}
                                `}
                                data-testid={`${testidPrefix}-thumb-${idx}`}
                            >
                                <img src={src} alt={`img-${idx}`} className="w-full h-full object-cover" />
                                {/* Hover controls */}
                                <div className="absolute inset-0 bg-black/0 group-hover:bg-black/55 transition flex items-center justify-center gap-1 opacity-0 group-hover:opacity-100">
                                    <button
                                        type="button"
                                        onClick={(e) => { e.stopPropagation(); setZoomSrc(src); }}
                                        className="h-6 w-6 rounded-full bg-white/95 text-foreground flex items-center justify-center hover:bg-white"
                                        title="Zoom"
                                        data-testid={`${testidPrefix}-zoom-${idx}`}
                                    >
                                        <ZoomIn className="h-3 w-3" />
                                    </button>
                                    {!isCover && (
                                        <button
                                            type="button"
                                            onClick={(e) => { e.stopPropagation(); setCover(idx); }}
                                            className="h-6 w-6 rounded-full bg-amber-400 text-white flex items-center justify-center hover:bg-amber-500"
                                            title="Set as cover"
                                            data-testid={`${testidPrefix}-setcover-${idx}`}
                                        >
                                            <Star className="h-3 w-3" />
                                        </button>
                                    )}
                                    <button
                                        type="button"
                                        onClick={(e) => { e.stopPropagation(); rotateAt(idx); }}
                                        className="h-6 w-6 rounded-full bg-white/95 text-foreground flex items-center justify-center hover:bg-white"
                                        title="Rotate 90°"
                                        data-testid={`${testidPrefix}-rotate-${idx}`}
                                    >
                                        <RotateCw className="h-3 w-3" />
                                    </button>
                                    <button
                                        type="button"
                                        onClick={(e) => { e.stopPropagation(); removeAt(idx); }}
                                        className="h-6 w-6 rounded-full bg-destructive text-white flex items-center justify-center hover:bg-destructive/90"
                                        title="Remove"
                                        data-testid={`${testidPrefix}-remove-${idx}`}
                                    >
                                        <Trash2 className="h-3 w-3" />
                                    </button>
                                </div>
                                {isCover && (
                                    <div className="absolute top-0.5 left-0.5 px-1 py-0.5 rounded bg-amber-500 text-white text-[9px] font-bold uppercase tracking-wider flex items-center gap-0.5">
                                        <Star className="h-2.5 w-2.5" /> Cover
                                    </div>
                                )}
                                <div className="absolute bottom-0.5 right-0.5 px-1 rounded bg-black/70 text-white text-[9px] font-bold">{idx + 1}</div>
                            </div>
                        );
                    })}
                    {canAdd && (
                        <button
                            type="button"
                            onClick={() => fileRef.current?.click()}
                            className="h-20 w-20 rounded-md border-2 border-dashed border-primary/40 bg-primary/5 hover:bg-primary/10 flex flex-col items-center justify-center transition"
                            data-testid={`${testidPrefix}-add-tile`}
                            title="Add more"
                        >
                            <Plus className="h-5 w-5 text-primary" />
                            <span className="text-[9px] text-primary font-bold mt-0.5 uppercase tracking-wider">Add</span>
                        </button>
                    )}
                </div>
            )}

            <input
                ref={fileRef}
                type="file"
                accept="image/png,image/jpeg,image/webp"
                multiple
                hidden
                onChange={(e) => { handleFiles(e.target.files); e.target.value = ""; }}
                data-testid={`${testidPrefix}-file-input`}
            />
            <input
                ref={cameraRef}
                type="file"
                accept="image/png,image/jpeg,image/webp"
                capture="environment"
                hidden
                onChange={(e) => { handleFiles(e.target.files); e.target.value = ""; }}
                data-testid={`${testidPrefix}-camera-input`}
            />

            {/* Zoom modal */}
            {zoomSrc && (
                <div
                    className="fixed inset-0 z-[1000] bg-black/85 backdrop-blur-sm flex items-center justify-center p-6"
                    onClick={() => setZoomSrc("")}
                    data-testid={`${testidPrefix}-zoom-modal`}
                >
                    <button
                        type="button"
                        onClick={() => setZoomSrc("")}
                        className="absolute top-4 right-4 h-10 w-10 rounded-full bg-white text-foreground hover:bg-white/90 flex items-center justify-center"
                        data-testid={`${testidPrefix}-zoom-close`}
                    >
                        <X className="h-5 w-5" />
                    </button>
                    <img
                        src={zoomSrc}
                        alt="zoom"
                        className="max-w-[90vw] max-h-[85vh] object-contain rounded-lg shadow-2xl"
                        onClick={(e) => e.stopPropagation()}
                    />
                </div>
            )}
        </div>
    );
}

export default MultiImageUploader;
