import React, { useState, useRef, useCallback, useEffect } from "react";
import { createPortal } from "react-dom";
import { useNavigate } from "react-router-dom";
import img from "../../assets/image/image.png";
import { getUserData } from "../../functions/getUserData";
import { useLoadingProgress, useProjectName } from "../../store/builder/store";
import OuterClick from "../../utils/outerClick";
import { KebabIcon } from "../icons/ExportCommonIcons";
import { getAllProjectsApi } from "../../services/dashboard/getAllProjectsApi";
import { useSocketStore } from "../../store/socket/useSocketStore";
import { Modal } from "../templates/PreviewModal";
// import { viewProject } from "../../services/dashboard/viewProject";
// import { updateProject } from "../../services/dashboard/updateProject";

interface DashBoardCardProps {
    projectName: string;
    thumbnail: string;
    projectId: string;
    createdAt?: string;
    isViewed?: string;
    createdBy?: { _id: string; userName: string };
    handleDeleteProject?: (projectId: string) => Promise<void>;
    handleTrashDeleteProject?: (projectId: string) => Promise<void>;
    handleRestoreProject?: (projectId: string) => Promise<void>;
    handleDuplicateWorkspaceProject?: (projectId: string, projectName: string, thumbnail: string, userId?: string) => Promise<void>;
    handleDuplicateRecentProject?: (projectId: string, projectName: string, thumbnail: string) => Promise<void>;
    active?: "shared" | "trash" | "recent" | string;
    setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
    setActiveFolder?: React.Dispatch<React.SetStateAction<string>>;
    openKebabProjectId: string | null;
    setOpenKebabProjectId: React.Dispatch<React.SetStateAction<string | null>>;
}

type RelativeTimeFormatUnit = "year" | "month" | "week" | "day" | "hour" | "minute" | "second";

const kebabOptionsMap: Record<string, string[]> = {
    default: ["rename", "delete", "duplicate", "open in new tab"],
    trash: ["restore", "delete"],
    shared: ["duplicate", "open in new tab"],
};

const DashboardCard: React.FC<DashBoardCardProps> = ({
    projectName,
    thumbnail,
    projectId,
    active,
    handleDeleteProject,
    handleRestoreProject,
    handleTrashDeleteProject,
    handleDuplicateWorkspaceProject,
    handleDuplicateRecentProject,
    createdAt,
    createdBy,
    setActiveFolder,
    openKebabProjectId,
    setOpenKebabProjectId,
}) => {
    const navigate = useNavigate();
    const { setProjectName } = useProjectName();
    const { userId, organization, userName } = getUserData();
    const { projectSocket } = useSocketStore();
    const { setLoadingProgress } = useLoadingProgress();

    const isKebabOpen = openKebabProjectId === projectId;
    const [renameValue, setRenameValue] = useState(projectName);
    const [isRenaming, setIsRenaming] = useState(false);
    const kebabRef = useRef<HTMLDivElement>(null);
    const [showDelete, setShowDelete] = useState(false);
    const [confirmText, setConfirmText] = useState("");

    // Close kebab when clicking outside
    OuterClick({
        contextClassName: [`tag-${projectId}`],
        setMenuVisible: () => {
            if (isKebabOpen) setOpenKebabProjectId(null);
        },
    });

    const navigateToProject = useCallback(() => {
        if (active === "trash") return;
        setLoadingProgress(1);
        setProjectName(projectName);
        navigate(`/projects/${projectId}`);
    }, [active, projectId, projectName, navigate, setLoadingProgress, setProjectName]);

    const getOptions = useCallback(() => {
        if (active === "trash") return kebabOptionsMap.trash;
        if (active === "shared" || (createdBy && createdBy._id !== userId)) {
            return kebabOptionsMap.shared;
        }
        return kebabOptionsMap.default;
    }, [active, createdBy, userId]);

    const handlePermanentDeleteConformation = () => {
        handleTrashDeleteProject?.(projectId);
        setShowDelete(false);
        setConfirmText("");
    };

    const handleProjectName = useCallback(
        async (newName: string) => {
            setRenameValue(newName);
            if (!projectId) return;

            try {
                const projects = await getAllProjectsApi();
                const projectUuid = projects?.Projects?.find((val: any) => val.projectUuid === projectId || val._id === projectId);
                if (!projectUuid) return;

                const updatePayload = {
                    projectId: projectUuid._id,
                    organization,
                    userId,
                    projectName: newName,
                };

                if (projectSocket) {
                    projectSocket.emit("v1:project:update", updatePayload);
                }
            } catch {
                // silent fail
            }
        },
        [projectId, userId, organization, projectSocket]
    );

    const handleOptionClick = useCallback(
        async (option: string) => {
            switch (option) {
                case "delete":
                    await (active === "trash" ? setShowDelete(true) : handleDeleteProject?.(projectId));
                    break;
                case "restore":
                    await handleRestoreProject?.(projectId);
                    break;
                case "open in new tab":
                    setProjectName(projectName);
                    window.open(`/projects/${projectId}`, "_blank");
                    break;
                case "rename":
                    setIsRenaming(true);
                    break;
                case "duplicate":
                    if (handleDuplicateWorkspaceProject) {
                        await handleDuplicateWorkspaceProject(projectId, projectName, thumbnail, userId);
                        if (active === "shared") {
                            setActiveFolder?.("myProjects");
                        }
                    } else if (handleDuplicateRecentProject) {
                        await handleDuplicateRecentProject(projectId, projectName, thumbnail);
                    }
                    break;
            }
        },
        [projectId, projectName, thumbnail, userId, active, handleDeleteProject, handleRestoreProject, handleDuplicateWorkspaceProject, handleDuplicateRecentProject, setProjectName, setActiveFolder]
    );

    const getRelativeTime = useCallback((dateString: string): string => {
        const date = new Date(dateString);
        const now = new Date();
        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);

        const intervals: Record<RelativeTimeFormatUnit, number> = {
            year: 31536000,
            month: 2592000,
            week: 604800,
            day: 86400,
            hour: 3600,
            minute: 60,
            second: 1,
        };

        const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
        for (const [unit, seconds] of Object.entries(intervals)) {
            const diff = Math.floor(diffInSeconds / seconds);
            if (diff >= 1) return rtf.format(-diff, unit as RelativeTimeFormatUnit);
        }
        return "just now";
    }, []);

    const [kebabPosition, setKebabPosition] = useState({ top: 0, left: 0 });

    useEffect(() => {
        if (isKebabOpen && kebabRef.current) {
            const rect = kebabRef.current.getBoundingClientRect();
            setKebabPosition({
                top: rect.bottom + window.scrollY,
                left: rect.left + window.scrollX - 80,
            });
        }
    }, [isKebabOpen]);

    return (
        <div className="dashboard-card-container" onClick={navigateToProject} title={projectName}>
            <div className="dashboard-card-wrapper">
                <div className="preview-container">
                    <img src={thumbnail || img} alt={`${projectName} thumbnail`} />
                </div>

                <div className="project-details-container" onClick={(e) => e.stopPropagation()}>
                    <div className="project-details">
                        {isRenaming ? (
                            <input
                                value={renameValue}
                                onChange={(e) => handleProjectName(e.target.value)}
                                onBlur={() => {
                                    setIsRenaming(false);
                                    setProjectName(renameValue);
                                }}
                                onKeyDown={(e) => {
                                    if (e.key === "Enter") {
                                        setIsRenaming(false);
                                        setProjectName(renameValue);
                                    }
                                }}
                                aria-label="Rename project"
                                autoFocus
                            />
                        ) : (
                            <span>{renameValue}</span>
                        )}
                        {createdAt && (
                            <div className="project-data">
                                {active === "trash" ? "Trashed" : "Edited"} {getRelativeTime(createdAt)}
                            </div>
                        )}
                    </div>

                    <div className="users-list-container" ref={kebabRef}>
                        <div className="user-profile">{(createdBy?.userName || userName || "A").charAt(0).toUpperCase()}</div>
                        <button
                            className="kebab-wrapper"
                            onClick={(e) => {
                                e.stopPropagation();
                                setOpenKebabProjectId(isKebabOpen ? null : projectId);
                            }}
                            aria-haspopup="true"
                            aria-expanded={isKebabOpen}
                            aria-label="Project options"
                        >
                            <KebabIcon />
                        </button>
                    </div>
                </div>
            </div>

            {isKebabOpen &&
                createPortal(
                    <div className={`kebab-options-wrapper tag-${projectId}`} style={{ position: "fixed", zIndex: 9999, ...kebabPosition }}>
                        {getOptions().map((option) => (
                            <button
                                key={option}
                                className="option"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    handleOptionClick(option);
                                    setOpenKebabProjectId(null);
                                }}
                            >
                                {option}
                            </button>
                        ))}
                    </div>,
                    document.body
                )}

            <Modal
                isOpen={showDelete}
                onClose={() => setShowDelete(false)}
                type="confirm"
                title="Delete Project"
                description={`This action is permanent. Please type ${projectName} to confirm.`}
                inputs={[
                    {
                        id: "confirmDelete",
                        label: "Confirmation",
                        placeholder: `Type ${projectName}`,
                        value: confirmText,
                        onChange: setConfirmText,
                    },
                ]}
                buttons={[
                    { label: "Cancel", onClick: () => setShowDelete(false), variant: "secondary" },
                    {
                        label: "Delete",
                        onClick: handlePermanentDeleteConformation,
                        variant: "danger",
                        disabled: confirmText !== projectName,
                    },
                ]}
            />
        </div>
    );
};

export default DashboardCard;
