import React, {
    useEffect,
    useState,
    useRef,
    forwardRef,
    useImperativeHandle,
} from "react";
import { usePage } from "@inertiajs/react";
import axios from "axios";
import {
    faSquareCheck,
    faTruck,
    faXmark,
    faBarcode, faArrowLeft, faQuestionCircle,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Item, ShipmentRequest } from "@/interfaces/interfaces";
import WarehouseExpediceDialog from "@/Components/WarehouseExpediceDialog";
import PdaView from "@/Pages/PdaView";

// Define an interface for the imperative handle exposed by a row.
interface RowHandle {
    triggerAnimation: () => void;
}

// ------------------- ParcelRow (for marking as processed) -------------------
interface ParcelRowProps {
    shipment: ShipmentRequest;
    onProcess: (shipment: ShipmentRequest) => void;
    onOpenDialog: (shipment: ShipmentRequest, type: "parcels") => void;
}

const ParcelRow = forwardRef<RowHandle, ParcelRowProps>(
    ({ shipment, onProcess, onOpenDialog }, ref) => {
        // "none" | "bounce" | "fade"
        const [animationPhase, setAnimationPhase] = useState<
            "none" | "bounce" | "fade"
        >("none");

        // Expose a method to trigger the animation from the parent (dialog)
        useImperativeHandle(ref, () => ({
            triggerAnimation: () => {
                setAnimationPhase("bounce");
                setTimeout(() => {
                    setAnimationPhase("fade");
                }, 1000);
                setTimeout(() => {
                    onProcess(shipment);
                }, 2000);
            },
        }));

        const handleRowClick = () => {
            onOpenDialog(shipment, "parcels");
        };

        const handleProcess = (e: React.MouseEvent) => {
            e.stopPropagation();
            setAnimationPhase("bounce");
            setTimeout(() => {
                setAnimationPhase("fade");
            }, 1000);
            setTimeout(() => {
                onProcess(shipment);
            }, 2000);
        };

        /* Determine classes based on the animation phase:
           - "none": border-base-300, bg-base-100, text-base-content
           - "bounce": border-primary, bg-primary, text-primary-content
           - "fade": border-primary, bg-primary, text-primary-content, opacity-0
        */
        const containerClasses = `
      p-4 border rounded-lg shadow flex flex-col space-y-3 transition-all duration-1000 cursor-pointer
      ${
            animationPhase === "none"
                ? "border-base-300 bg-base-100 text-base-content opacity-100"
                : animationPhase === "bounce"
                    ? "border-primary bg-primary text-primary-content opacity-100"
                    : "border-primary bg-primary text-primary-content opacity-0"
        }
    `;

        return (
            <div onClick={handleRowClick} className={containerClasses}>
                <div>
                    <p className="font-bold">{shipment.shipment_reference}</p>
                    <div className="mt-2 space-y-2">
                        {shipment.items.map((item) => (
                            <div key={item.id} className="border-t-2 border-warning pt-2 space-y-1">
                                <p className="text-base-content">
                                    {item.quantity}× {item.name}
                                </p>
                                <div className="flex justify-between text-sm text-base-content">
                                    <p>{item.model_number}</p>
                                    <p>
                                        {(item.price / item.quantity).toFixed(2)}{" "}
                                        {shipment.currency}
                                    </p>
                                </div>
                                <div
                                    className={`mt-2 flex flex-wrap gap-2 p-2 border rounded-lg transition-colors duration-300 ${
                                        animationPhase === "bounce"
                                            ? "bg-primary text-primary-content"
                                            : "bg-base-200 text-base-content"
                                    } border-base-300`}
                                >
                                    {Object.entries(item.stockData).map(
                                        ([stockName, stockArray]) =>
                                            stockArray.map((stock, idx) => (
                                                <div key={`${stockName}-${idx}`} className="text-sm">
                                                    <p className="font-semibold">{stockName}</p>
                                                    <p>Sklad: {stock.location}</p>
                                                    <p>{stock.count} ks</p>
                                                </div>
                                            ))
                                    )}
                                </div>
                            </div>
                        ))}
                    </div>
                </div>
                {animationPhase === "bounce" ? (
                    <FontAwesomeIcon
                        icon={faSquareCheck}
                        className="w-8 h-8 text-primary animate-bounce"
                    />
                ) : (
                    <button
                        onClick={handleProcess}
                        className="btn btn-primary btn-sm self-end"
                    >
                        Process
                    </button>
                )}
            </div>
        );
    }
);

// ------------------- ProcessedRow (for marking as unprocessed) -------------------
interface ProcessedRowProps {
    shipment: ShipmentRequest;
    onUnprocess: (shipment: ShipmentRequest) => void;
    onOpenDialog: (shipment: ShipmentRequest, type: "processed") => void;
}

const ProcessedRow = forwardRef<RowHandle, ProcessedRowProps>(
    ({ shipment, onUnprocess, onOpenDialog }, ref) => {
        const [animationPhase, setAnimationPhase] = useState<
            "none" | "bounce" | "fade"
        >("none");

        useImperativeHandle(ref, () => ({
            triggerAnimation: () => {
                setAnimationPhase("bounce");
                setTimeout(() => {
                    setAnimationPhase("fade");
                }, 1000);
                setTimeout(() => {
                    onUnprocess(shipment);
                }, 2000);
            },
        }));

        const handleRowClick = () => {
            onOpenDialog(shipment, "processed");
        };

        const handleUnprocess = (e: React.MouseEvent) => {
            e.stopPropagation();
            setAnimationPhase("bounce");
            setTimeout(() => {
                setAnimationPhase("fade");
            }, 1000);
            setTimeout(() => {
                onUnprocess(shipment);
            }, 2000);
        };

        /* Determine classes based on the animation phase:
           - "none": border-base-300, bg-base-100, text-base-content
           - "bounce": border-error, bg-error, text-error-content
           - "fade": border-error, bg-error, text-error-content, opacity-0
        */
        const containerClasses = `
      p-4 border rounded-lg shadow flex flex-col space-y-3 transition-all duration-1000 cursor-pointer
      ${
            animationPhase === "none"
                ? "border-base-300 bg-base-100 text-base-content opacity-100"
                : animationPhase === "bounce"
                    ? "border-error bg-error text-error-content opacity-100"
                    : "border-error bg-error text-error-content opacity-0"
        }
    `;

        return (
            <div onClick={handleRowClick} className={containerClasses}>
                <div>
                    <p className="font-bold">{shipment.shipment_reference}</p>
                    <div className="mt-2 space-y-2">
                        {shipment.items.map((item) => (
                            <div key={item.id} className="border-t-2 border-warning pt-2 space-y-1">
                                <p className="text-base-content">
                                    {item.quantity}× {item.name}
                                </p>
                                <div className="flex justify-between text-sm text-base-content">
                                    <p>{item.model_number}</p>
                                    <p>
                                        {(item.price / item.quantity).toFixed(2)}{" "}
                                        {shipment.currency}
                                    </p>
                                </div>
                                <div
                                    className={`mt-2 flex flex-wrap gap-2 p-2 border rounded-lg transition-colors duration-300 ${
                                        animationPhase === "bounce"
                                            ? "bg-error text-error-content"
                                            : "bg-base-200 text-base-content"
                                    } border-base-300`}
                                >
                                    {Object.entries(item.stockData).map(
                                        ([stockName, stockArray]) =>
                                            stockArray.map((stock, idx) => (
                                                <div key={`${stockName}-${idx}`} className="text-sm">
                                                    <p className="font-semibold">{stockName}</p>
                                                    <p>Sklad: {stock.location}</p>
                                                    <p>{stock.count} ks</p>
                                                </div>
                                            ))
                                    )}
                                </div>
                            </div>
                        ))}
                    </div>
                </div>
                {animationPhase === "bounce" ? (
                    <FontAwesomeIcon
                        icon={faXmark}
                        className="w-8 h-8 text-error animate-bounce"
                    />
                ) : (
                    <button
                        onClick={handleUnprocess}
                        className="btn btn-error btn-sm self-end"
                    >
                        Unprocess
                    </button>
                )}
            </div>
        );
    }
);

type InertiaProps = {
    auth: any; // adjust per your auth type
    selectedBatchID: number;
};

// ------------------- Main Component -------------------
export default function WarehouseExpedicePage() {
    const { selectedBatchID } = usePage<InertiaProps>().props;

    // States for shipments
    const [parcels, setParcels] = useState<ShipmentRequest[]>([]);
    const [parcelsOther, setParcelsOther] = useState<ShipmentRequest[]>([]);
    const [processed, setProcessed] = useState<ShipmentRequest[]>([]);
    const [loading, setLoading] = useState(true);

    // Refs to control individual row animations
    const parcelRowRefs = useRef<{ [key: number]: RowHandle | null }>({});
    const processedRowRefs = useRef<{ [key: number]: RowHandle | null }>({});

    // Dialog state
    const [selectedShipment, setSelectedShipment] =
        useState<ShipmentRequest | null>(null);
    const [selectedType, setSelectedType] = useState<
        "parcels" | "processed" | null
    >(null);
    const [isDialogOpen, setIsDialogOpen] = useState(false);

    const handleCopyToClipboard = () => {
        const copyString = parcels.map((p) => p.shipment_reference).join(",");
        const copyStringOther = parcelsOther.map((p) => p.shipment_reference).join(
            ","
        );
        const copyStringProcessed = processed
            .map((p) => p.shipment_reference)
            .join(",");

        navigator.clipboard
            .writeText([copyString, copyStringOther, copyStringProcessed].filter(Boolean).join(","))
            .then(() => {
                alert("Parcels copied to clipboard!");
            })
            .catch((err) => {
                console.error("Failed to copy:", err);
            });
    };

    useEffect(() => {
        axios
            .post("/api/expediceListWMS", { batch_id: selectedBatchID })
            .then((response) => {
                setParcels(response.data.batch_items.shipments);
                setParcelsOther(response.data.batch_items.shipments_other);
                setLoading(false);
            })
            .catch((error) => {
                console.error("Error fetching data:", error);
                setLoading(false);
            });
    }, [selectedBatchID]);

    // Move a shipment from Parcels to Processed
    const markAsProcessed = (shipment: ShipmentRequest) => {
        setParcels((prev) => prev.filter((s) => s.id !== shipment.id));
        setProcessed((prev) => [...prev, shipment]);
    };

    // Move a shipment from Processed back to Parcels
    const markAsUnprocessed = (shipment: ShipmentRequest) => {
        setProcessed((prev) => prev.filter((s) => s.id !== shipment.id));
        setParcels((prev) => [...prev, shipment]);
    };

    // Open the dialog for a shipment
    const openDialog = (
        shipment: ShipmentRequest,
        type: "parcels" | "processed"
    ) => {
        setSelectedShipment(shipment);
        setSelectedType(type);
        setIsDialogOpen(true);
    };

    // Close the dialog
    const closeDialog = () => {
        setIsDialogOpen(false);
        setSelectedShipment(null);
        setSelectedType(null);
    };

    const pdaDialogRef = useRef<HTMLDialogElement>(null);
    const openPdaModal = () => {
        pdaDialogRef.current?.showModal();
    };
    const closePdaModal = () => {
        pdaDialogRef.current?.close();
    };

    const [buttonStates, setButtonStates] = useState<{ [itemId: number]: any }>(
        {}
    );

    // Handle processing/unprocessing via the dialog action button
    const handleDialogProcess = () => {
        if (selectedShipment && selectedType === "parcels") {
            const filteredButtonStates = selectedShipment.items.reduce(
                (acc: any, item: Item) => {
                    if (buttonStates[item.id]) {
                        acc[item.id] = buttonStates[item.id];
                    }
                    return acc;
                },
                {}
            );

            axios
                .post("/api/warehouseExpedice/passOptions", {
                    shipment_request_id: selectedShipment.id,
                    buttonStates: filteredButtonStates,
                    shipment_items: selectedShipment.items,
                })
                .catch((error) => {
                    console.error("Error sending button states:", error);
                });

            if (parcelRowRefs.current[selectedShipment.id]) {
                parcelRowRefs.current[selectedShipment.id]?.triggerAnimation();
            } else {
                markAsProcessed(selectedShipment);
            }
        } else if (selectedShipment && selectedType === "processed") {
            if (processedRowRefs.current[selectedShipment.id]) {
                processedRowRefs.current[selectedShipment.id]?.triggerAnimation();
            } else {
                markAsUnprocessed(selectedShipment);
            }
        }
        closeDialog();
    };

    if (loading) {
        return <div className="p-4 text-base-content">Loading...</div>;
    }

    return (
        <>
            {/* Top bar */}
            <div className="flex justify-between items-center bg-base-100 p-4 shadow">

                <a className="link" href={route('dashboard')}><FontAwesomeIcon icon={faArrowLeft} /> Back</a>
                <button className="btn btn-ghost">
                    <FontAwesomeIcon icon={faQuestionCircle} /> Help
                </button>
            </div>
            {/* Open the modal using document.getElementById('ID').showModal() method */}
            <button className="btn" onClick={()=>openPdaModal()}>open modal</button>
            {/* PDA VIEW DIALOG */}
            <dialog id="pdaViewModal" className="modal" ref={pdaDialogRef}>
                <div className="modal-box max-w-4xl max-h-[90vh] overflow-hidden p-0">
                    <PdaView closeParent={closePdaModal} />
                </div>
                <form method="dialog" className="modal-backdrop">
                    <button className="btn">Close</button>
                </form>
            </dialog>
            {/* Tabs */}
            <div className="tabs tabs-box w-full">
                {/* Parcels Tab */}
                <label className="tab flex-1">
                    <input
                        type="radio"
                        name="expedice_tabs"
                        className="tab"
                        aria-label="Parcels"
                        defaultChecked
                    />
                    <div className="flex items-center justify-center gap-2 w-full">
                        <FontAwesomeIcon icon={faTruck} className="w-5 h-5" />
                        <span className="text-base-content">Parcels</span>
                    </div>
                </label>
                <div className="tab-content bg-base-100 border-base-300 p-6">
                    <div className="space-y-3">
                        {parcels.length === 0 ? (
                            <p className="text-base-content">No parcels available.</p>
                        ) : (
                            parcels.map((shipment) => (
                                <ParcelRow
                                    ref={(el) => {
                                        parcelRowRefs.current[shipment.id] = el;
                                    }}
                                    key={shipment.id}
                                    shipment={shipment}
                                    onProcess={markAsProcessed}
                                    onOpenDialog={openDialog}
                                />
                            ))
                        )}
                    </div>
                </div>

                {/* Nahravacky Tab */}
                <label className="tab flex-1">
                    <input
                        type="radio"
                        name="expedice_tabs"
                        className="tab"
                        aria-label="Nahravacky"
                    />
                    <div className="flex items-center justify-center gap-2 w-full">
                        <FontAwesomeIcon icon={faBarcode} className="w-5 h-5" />
                        <span className="text-base-content">Nahravacky</span>
                    </div>
                </label>
                <div className="tab-content bg-base-100 border-base-300 p-6">
                    <div className="space-y-3">
                        {parcelsOther.length === 0 ? (
                            <p className="text-base-content">No parcels available.</p>
                        ) : (
                            parcelsOther.map((shipment) => (
                                <ParcelRow
                                    ref={(el) => {
                                        parcelRowRefs.current[shipment.id] = el;
                                    }}
                                    key={shipment.id}
                                    shipment={shipment}
                                    onProcess={markAsProcessed}
                                    onOpenDialog={openDialog}
                                />
                            ))
                        )}
                    </div>
                </div>

                {/* Processed Tab (15% width) */}
                <label className="tab w-[15%] flex-none">
                    <input
                        type="radio"
                        name="expedice_tabs"
                        className="tab"
                        aria-label="Processed"
                    />
                    <div className="flex items-center justify-center w-full">
                        <FontAwesomeIcon icon={faSquareCheck} className="w-5 h-5" />
                    </div>
                </label>
                <div className="tab-content bg-base-100 border-base-300 p-6">
                    <div className="space-y-3">
                        {processed.length === 0 ? (
                            <p className="text-base-content">No processed shipments.</p>
                        ) : (
                            processed.map((shipment) => (
                                <ProcessedRow
                                    ref={(el) => {
                                        processedRowRefs.current[shipment.id] = el;
                                    }}
                                    key={shipment.id}
                                    shipment={shipment}
                                    onUnprocess={markAsUnprocessed}
                                    onOpenDialog={openDialog}
                                />
                            ))
                        )}
                    </div>
                </div>
            </div>

            {/* Shipment Details Dialog */}
            {selectedShipment && (
                <WarehouseExpediceDialog
                    selectedShipment={selectedShipment}
                    isDialogOpen={isDialogOpen}
                    closeDialog={closeDialog}
                    handleDialogProcess={handleDialogProcess}
                    selectedType={selectedType}
                    buttonStates={buttonStates}
                    setButtonStates={setButtonStates}
                />
            )}
        </>
    );
}
