"use client";

import Image from "next/image";
import { Edit, Trash2, Type } from "lucide-react";
import { useEffect, useState } from "react";

import api from "@/api/axios";
import { toast } from "sonner";
import { getGuestUuid } from "@/utils/guestUuid";

type MonthlyCalendarImage = {
    id: number | string;
    image?: string;
    cropped_image?: string | null;
    selected_crop_image?: string | null;
    updated_at?: string;
    uploadStatus?: "pending" | "uploading" | "success" | "failed";
    monthIndex?: number;
    sort_order?: number;
    calendar_slot?: string;
    calendar_type?: string;
    caption_text?: string;
};

type Props = {
    images: MonthlyCalendarImage[];
    selectedEffect: string;
    backgroundColor: string;
    effects: any;
    isUploadingImage: (img: any) => boolean;
    removeImage: (id: string) => void;
    onOpenUpload: (slotIndex?: number) => void;
    onEditImage?: (image: MonthlyCalendarImage) => void;
    setImages?: (value: any) => void;

    qty: number;
    increaseQty: () => void;
    decreaseQty: () => void;

    imageTexts?: Record<string, string>;
    updateImageText?: (imageId: string | number, value: string) => void;
};

const MONTHS = [
    { key: "january", label: "January" },
    { key: "february", label: "February" },
    { key: "march", label: "March" },
    { key: "april", label: "April" },
    { key: "may", label: "May" },
    { key: "june", label: "June" },
    { key: "july", label: "July" },
    { key: "august", label: "August" },
    { key: "september", label: "September" },
    { key: "october", label: "October" },
    { key: "november", label: "November" },
    { key: "december", label: "December" },
];

const getMonthlyTemplateUrl = (monthKey: string) => {
    return `${process.env.NEXT_PUBLIC_STORAGE_URL}/monthly-templates/${monthKey}.jpg`;
};

const photoAreaStyle: React.CSSProperties = {
    top: "3.85%",
    left: "3.63%",
    width: "92.68%",
    height: "44.89%",
};

export default function MonthlyCalendarV2({
                                              images,
                                              selectedEffect,
                                              backgroundColor,
                                              effects,
                                              isUploadingImage,
                                              removeImage,
                                              onOpenUpload,
                                              onEditImage,
                                              setImages,
                                              qty,
                                              increaseQty,
                                              decreaseQty,
                                              imageTexts = {},
                                              updateImageText,
                                          }: Props) {
    const [slotImages, setSlotImages] = useState<Array<MonthlyCalendarImage | null>>(
        new Array(12).fill(null)
    );

    const [dragIndex, setDragIndex] = useState<number | null>(null);
    const [dragOverIndex, setDragOverIndex] = useState<number | null>(null);

    const [selectedFont, setSelectedFont] = useState<Record<string, string>>({});

    const [openFontMenuId, setOpenFontMenuId] = useState<string | null>(null);

    const fontOptions = [
        {
            label: "مرحبا",
            fontFamily: "Arial",
            fontSize: "0.9em",
            letterSpacing: "1px",
        },
        {
            label: "مرحبا",
            fontFamily: "Courier New",
            fontSize: "0.9em",
            letterSpacing: "1px",
        },
        {
            label: "مرحبا",
            fontFamily: "Yellowtail",
            fontSize: "0.9em",
            letterSpacing: "1px",
        },
    ];

    useEffect(() => {
        setSlotImages((prev) => {
            const currentImages = images.filter((img) => img?.id).slice(0, 12);

            const next = new Array(12).fill(null) as Array<MonthlyCalendarImage | null>;

            currentImages.forEach((img, fallbackIndex) => {
                const slotIndexFromCalendarSlot = MONTHS.findIndex(
                    (month) => month.label === img.calendar_slot || month.key === img.calendar_slot
                );

                const index =
                    typeof img.monthIndex === "number" && img.monthIndex >= 0 && img.monthIndex < 12
                        ? img.monthIndex
                        : img.sort_order && Number(img.sort_order) >= 1 && Number(img.sort_order) <= 12
                            ? Number(img.sort_order) - 1
                            : slotIndexFromCalendarSlot >= 0
                                ? slotIndexFromCalendarSlot
                                : fallbackIndex;

                next[index] = {
                    ...img,
                    monthIndex: index,
                };
            });

            return next;
        });
    }, [images]);

    const syncParentImages = (nextSlots: Array<MonthlyCalendarImage | null>) => {
        const ordered = nextSlots
            .map((img, index) => {
                if (!img?.id) return null;

                const imageId = String(img.id);

                return {
                    ...img,
                    monthIndex: index,
                    sort_order: index + 1,
                    calendar_slot: MONTHS[index].label,
                    calendar_type: "monthly",
                    caption_text:
                        imageTexts[imageId] ??
                        img.caption_text ??
                        "",
                };
            })
            .filter(Boolean);

        setImages?.(ordered);
    };

    const getImageSrc = (img: MonthlyCalendarImage) => {
        return img.cropped_image || img.selected_crop_image || img.image || "";
    };

    const getImageUrl = (img: MonthlyCalendarImage) => {
        const src = getImageSrc(img);

        if (!src) return "";

        if (src.startsWith("blob:")) {
            return src;
        }

        const version = img.updated_at || img.id;

        return `${src}${src.includes("?") ? "&" : "?"}v=${encodeURIComponent(String(version))}`;
    };

    const swapImages = (fromIndex: number, toIndex: number) => {
        if (fromIndex === toIndex) return;

        const fromImg = slotImages[fromIndex];
        const toImg = slotImages[toIndex];

        if (!fromImg?.id || !toImg?.id) return;

        const next = [...slotImages];

        next[fromIndex] = {
            ...toImg,
            monthIndex: fromIndex,
            sort_order: fromIndex + 1,
            calendar_slot: MONTHS[fromIndex].label,
            calendar_type: "monthly",
        };

        next[toIndex] = {
            ...fromImg,
            monthIndex: toIndex,
            sort_order: toIndex + 1,
            calendar_slot: MONTHS[toIndex].label,
            calendar_type: "monthly",
        };

        setSlotImages(next);
        syncParentImages(next);

        sendReOrderData(next);
    };

    const handleDragStart = (index: number) => {
        if (!slotImages[index]?.id) return;
        setDragIndex(index);
    };

    const handleDragOver = (
        e: React.DragEvent<HTMLDivElement>,
        index: number
    ) => {
        e.preventDefault();

        if (!slotImages[index]?.id) {
            setDragOverIndex(null);
            return;
        }

        setDragOverIndex(index);
    };

    const handleDrop = (
        e: React.DragEvent<HTMLDivElement>,
        dropIndex: number
    ) => {
        e.preventDefault();

        if (dragIndex === null) return;

        swapImages(dragIndex, dropIndex);

        setDragIndex(null);
        setDragOverIndex(null);
    };

    const handleDragEnd = () => {
        setDragIndex(null);
        setDragOverIndex(null);
    };

    const handleRemoveSlotImage = (index: number, imageId: string) => {
        const next = [...slotImages];

        next[index] = null;

        setSlotImages(next);
        syncParentImages(next);

        removeImage(imageId);
    };

    const filledCount = slotImages.filter((img) => img?.id).length;

    const sendReOrderData = async (nextSlots: Array<MonthlyCalendarImage | null>) => {
        try {
            const guestUuid = getGuestUuid();

            const reOrderData = nextSlots
                .map((item, slotIndex) => {
                    if (!item?.id || String(item.id).startsWith("temp-")) {
                        return null;
                    }

                    const imageId = String(item.id);

                    return {
                        image_id: item.id,
                        sort_order: slotIndex + 1,
                        calendar_slot: MONTHS[slotIndex].label,
                        calendar_type: "monthly",
                        caption_text:
                            imageTexts[imageId] ??
                            item.caption_text ??
                            "",
                    };
                })
                .filter(Boolean);

            if (reOrderData.length === 0) return;

            await api.post(
                "account-images/re-order",
                {
                    guest_uuid: guestUuid,
                    images: reOrderData,
                },
                {
                    headers: {
                        ...(guestUuid ? { "X-Guest-Uuid": guestUuid } : {}),
                    },
                }
            );
        } catch (error) {
            console.error("Error saving monthly calendar order:", error);
            toast.error("فشل في حفظ ترتيب الصور");
        }
    };

    return (
        <div className="w-full mx-auto mt-8 mb-28 flex flex-col items-center">
            <div className="w-full flex justify-center mb-4">
                <button
                    type="button"
                    onClick={() => onOpenUpload()}
                    className="flex items-center gap-2 bg-white border border-[#E2E2E2] rounded-full px-5 py-3 shadow-sm text-[#FF2B77] font-medium"
                >
                    <span className="text-xl leading-none">+</span>
                    <span>إضافة صور</span>
                    <span className="text-gray-500 text-sm">{filledCount}/12</span>
                </button>
            </div>

            <div className="w-full max-w-[1200px] mx-auto flex flex-wrap justify-center">
                {MONTHS.map((month, index) => {
                    const img = slotImages[index];
                    const imageUrl = img ? getImageUrl(img) : "";
                    const isUploading = img ? isUploadingImage(img) : false;
                    const imageId = img?.id ? String(img.id) : "";
                    const currentText =
                        imageId && imageTexts[imageId] !== undefined
                            ? imageTexts[imageId]
                            : img?.caption_text ?? "";

                    return (
                        <div
                            key={month.key}
                            className="w-full sm:w-1/2 lg:w-1/3 px-[15px] mb-[30px]"
                        >
                            <div className="relative text-center w-full">

                                <div
                                    draggable={!!img?.id}
                                    onDragStart={() => handleDragStart(index)}
                                    onDragOver={(e) => handleDragOver(e, index)}
                                    onDrop={(e) => handleDrop(e, index)}
                                    onDragEnd={handleDragEnd}
                                    className={`relative w-full bg-white shadow-md transition-all ${
                                        img ? "cursor-move" : "cursor-pointer"
                                    } ${
                                        dragOverIndex === index
                                            ? "ring-4 ring-[#FF2B77] z-20"
                                            : ""
                                    }`}
                                    style={{ backgroundColor }}
                                    onClick={() => {
                                        if (!img) onOpenUpload(index);
                                    }}
                                >
                                    <img
                                        src={getMonthlyTemplateUrl(month.key)}
                                        alt={`${month.label} template`}
                                        className="block w-full h-auto select-none pointer-events-none"
                                        draggable={false}
                                    />

                                    <div
                                        className="absolute overflow-hidden bg-gray-100"
                                        style={photoAreaStyle}
                                    >
                                        {img && imageUrl ? (
                                            <>
                                                <img
                                                    src={imageUrl}
                                                    alt={`${month.label} photo`}
                                                    className="w-full h-full object-cover select-none"
                                                    draggable={false}
                                                    style={{
                                                        filter:
                                                            effects?.[
                                                                selectedEffect as keyof typeof effects
                                                                ] ?? "none",
                                                    }}
                                                />

                                                {isUploading && (
                                                    <div className="absolute inset-0 bg-white/70 flex items-center justify-center text-xs text-gray-700 z-20">
                                                        جاري الرفع...
                                                    </div>
                                                )}
                                            </>
                                        ) : (
                                            <button
                                                type="button"
                                                onClick={(e) => {
                                                    e.stopPropagation();
                                                    onOpenUpload(index);
                                                }}
                                                className="w-full h-full flex flex-col items-center justify-center text-gray-400 hover:text-[#FF2B77] bg-gray-100"
                                            >
                                                <span className="text-2xl leading-none">+</span>
                                                <span className="text-[11px] mt-1">إضافة صورة</span>
                                            </button>
                                        )}
                                    </div>


                                    {img && (
                                        <input
                                            value={currentText}
                                            maxLength={26}
                                            onClick={(e) => e.stopPropagation()}
                                            onChange={(e) =>
                                                updateImageText?.(img.id, e.target.value)
                                            }
                                            placeholder="أضف نصًا"
                                            className="absolute bg-transparent text-center outline-none border-0 p-0 m-0"
                                            style={{
                                                top: "50.5%",
                                                left: "8%",
                                                width: "75%",
                                                color: "rgb(0, 0, 0)",
                                                fontFamily: selectedFont[imageId] || "Arial",
                                                fontSize: "0.9em",
                                                letterSpacing: "1px",
                                            }}
                                        />
                                    )}
                                </div>
                            </div>
                            {img && (
                                <div className="relative flex items-center justify-center gap-10 mt-3">
                                    <button
                                        type="button"
                                        onClick={() => onEditImage?.(img)}
                                        className="font-bold text-xl text-gray-900"
                                        title="تعديل الصورة"
                                    >
                                        <Edit size={20} />
                                    </button>

                                    <div className="relative">
                                        <button
                                            type="button"
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setOpenFontMenuId((current) =>
                                                    current === imageId ? null : imageId
                                                );
                                            }}
                                            className="font-bold text-xl text-gray-900"
                                            title="تغيير الخط"
                                        >
                                            <Type size={22} />
                                        </button>

                                        {openFontMenuId === imageId && (
                                            <ul className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 z-50 bg-white border border-gray-200 rounded shadow-lg min-w-[220px] py-2 flex justify-around">
                                                {fontOptions.map((font) => {
                                                    const isActive =
                                                        (selectedFont[imageId] || "Arial") === font.fontFamily;

                                                    return (
                                                        <li
                                                            key={font.fontFamily}
                                                            onClick={(e) => {
                                                                e.stopPropagation();

                                                                setSelectedFont((prev) => ({
                                                                    ...prev,
                                                                    [imageId]: font.fontFamily,
                                                                }));

                                                                setOpenFontMenuId(null);
                                                            }}
                                                            className={`cursor-pointer px-4 py-2 text-sm opacity-60 hover:opacity-100 ${
                                                                isActive ? "opacity-100 font-bold" : ""
                                                            }`}
                                                            style={{
                                                                fontFamily: font.fontFamily,
                                                                fontSize: font.fontSize,
                                                                letterSpacing: font.letterSpacing,
                                                            }}
                                                        >
                                                            {font.label}
                                                        </li>
                                                    );
                                                })}
                                            </ul>
                                        )}
                                    </div>

                                    <button
                                        type="button"
                                        onClick={() => handleRemoveSlotImage(index, String(img.id))}
                                        className="font-bold text-xl text-red-500"
                                        title="حذف الصورة"
                                    >
                                        <Trash2 size={20} />
                                    </button>
                                </div>
                            )}
                        </div>
                    );
                })}
            </div>

            <div className="bg-white content-ltr rounded-2xl shadow-lg flex items-center justify-around w-[390px] py-4 px-3 mt-6 mb-4">
                <button
                    className="flex flex-col items-center text-pink-500 cursor-pointer"
                    onClick={() => onOpenUpload()}
                    type="button"
                >
                    <div className="bg-pink-100 p-3 rounded-[16px] mb-2">
                        <Image src="/icons/plus.svg" alt="plus" width={24} height={24} />
                    </div>
                    <span className="text-xs">إضافة صور</span>
                </button>

                <div className="flex flex-col items-center text-gray-700">
                    <span className="text-xs mb-2">الكمية</span>

                    <div className="flex items-center gap-3">
                        <button
                            type="button"
                            onClick={decreaseQty}
                            className="w-8 h-8 rounded-full border border-gray-300 flex items-center justify-center"
                        >
                            -
                        </button>

                        <span className="min-w-6 text-center font-semibold">{qty}</span>

                        <button
                            type="button"
                            onClick={increaseQty}
                            className="w-8 h-8 rounded-full border border-gray-300 flex items-center justify-center"
                        >
                            +
                        </button>
                    </div>
                </div>

                <div className="flex flex-col items-center text-gray-600">
                    <div className="border border-[#F1F2F9] p-3 rounded-[16px] mb-2">
                        <span className="text-sm font-semibold">{filledCount}/12</span>
                    </div>
                    <span className="text-xs">الصور</span>
                </div>
            </div>

            <p className="text-xs text-gray-500 text-center -mt-2">
                اسحب الصورة وضعها فوق صورة أخرى لتبديل الترتيب
            </p>
        </div>
    );
}