import React, { useEffect, useState } from "react";
import { getUserData } from "../../functions/getUserData";
import { useSocketStore } from "../../store/socket/useSocketStore";

import ProjectSocketRes from "./socket/projectSocketRes";
import DashboardNavBar from "./DashboardNavBar";
import DashboardCard from "./DashboardCard";
import MarketPlaceBanner from "./MarketPlaceBanner";

import { getAllProjectsApi } from "../../services/dashboard/getAllProjectsApi";
import { sharedWithMeProjectsApi } from "../../services/dashboard/sharedWithMeProjectApi";
import { recentlyViewedApi } from "../../services/dashboard/recentlyViewedApi";
import { getTrashApi } from "../../services/dashboard/getTrashApi";
import { searchProjectApi } from "../../services/dashboard/searchProjectsApi";
import { trashSearchProjectApi } from "../../services/dashboard/trashSearchProjectApi";
import { restoreTrashApi } from "../../services/dashboard/restoreTrashApi";
import { generateUniqueId } from "../../functions/generateUniqueId";

interface DashboardMainProps {
    activeFolder: Folder;
}

const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
    const [activeSubFolder, setActiveSubFolder] = useState("myProjects");
    const [projectsData, setProjectsData] = useState<DashboardProjectCollection>({});
    const [projectsCache, setProjectsCache] = useState<Record<string, DashboardProjectCollection>>({});
    const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
    const [openKebabProjectId, setOpenKebabProjectId] = useState<string | null>(null);

    const { userId, organization } = getUserData();
    const { projectSocket } = useSocketStore();

    // 🔹 Fetch all folders on mount and store locally
    const fetchAllData = async () => {
        try {
            const [homeProjects, myProjects, sharedProjects, trashProjects] = await Promise.all([recentlyViewedApi(), getAllProjectsApi(), sharedWithMeProjectsApi(), getTrashApi()]);

            const cache: Record<string, DashboardProjectCollection> = {
                home: homeProjects,
                "projects-myProjects": myProjects,
                "projects-shared": sharedProjects,
                trash: trashProjects,
            };

            setProjectsCache(cache);

            // set current active data
            const cacheKey = activeFolder === "projects" ? `projects-${activeSubFolder}` : activeFolder;
            if (cache[cacheKey]) {
                setProjectsData(cache[cacheKey]);
            }
        } catch (error) {
            console.error("Failed to fetch dashboard data:", error);
        }
    };

    // 🔹 On mount fetch once
    useEffect(() => {
        fetchAllData();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    // 🔹 Switch folder/subFolder from cache
    useEffect(() => {
        if (!isSearchActive) {
            const cacheKey = activeFolder === "projects" ? `projects-${activeSubFolder}` : activeFolder;
            if (projectsCache[cacheKey]) {
                setProjectsData(projectsCache[cacheKey]);
            }
        }
    }, [activeFolder, activeSubFolder, isSearchActive, projectsCache]);

    // 🔹 Search handler
    const handleSearch = async (inputValue: string) => {
        if (!inputValue.trim()) {
            setIsSearchActive(false);
            return;
        }

        let results;
        if (activeFolder === "trash") {
            results = await trashSearchProjectApi(inputValue);
        } else {
            results = await searchProjectApi(inputValue);
        }

        setIsSearchActive(true);
        setProjectsData(results?.message ? {} : results);
    };

    // 🔹 Socket Actions
    const updateStateAfterRemove = (projectId: string) => {
        setProjectsData((prev: DashboardProjectCollection) => {
            const key = Object.keys(prev)[0];
            const updatedList = prev[key]?.filter((p) => p._id !== projectId) || [];
            return { ...prev, [key]: updatedList };
        });

        setProjectsCache((prev) => {
            const newCache = { ...prev };
            Object.keys(newCache).forEach((k) => {
                const key = Object.keys(newCache[k])[0];
                newCache[k] = {
                    ...newCache[k],
                    [key]: newCache[k][key]?.filter((p) => p._id !== projectId) || [],
                };
            });
            return newCache;
        });

        setIsSearchActive(false);
    };

    const handleDelete = async (projectId: string): Promise<void> => {
        if (projectSocket) {
            projectSocket.emit("v1:project:delete", { projectId, organization, userId });
        }
        updateStateAfterRemove(projectId);

        // 🔹 Refresh trash folder cache (since project moves there)
        const trashProjects = await getTrashApi();
        setProjectsCache((prev) => ({ ...prev, trash: trashProjects }));
    };

    const handlePermanentDelete = async (deleteTargetId: string): Promise<void> => {
        console.log("deleteTargetId: ", deleteTargetId);
        if (!deleteTargetId) return;
        if (projectSocket) {
            projectSocket.emit("v1:trash:delete", {
                projectId: deleteTargetId,
                organization,
                userId,
            });
        }
        updateStateAfterRemove(deleteTargetId);

        // 🔹 Refresh trash folder
        const trashProjects = await getTrashApi();
        console.log("trashProjects: ", trashProjects);
        setProjectsCache((prev) => ({ ...prev, trash: trashProjects }));
    };

    const handleRestore = async (projectId: string): Promise<void> => {
        await restoreTrashApi(projectId);
        updateStateAfterRemove(projectId);

        // 🔹 Refresh home & projects-myProjects
        const [homeProjects, myProjects] = await Promise.all([recentlyViewedApi(), getAllProjectsApi()]);
        setProjectsCache((prev) => ({
            ...prev,
            home: homeProjects,
            "projects-myProjects": myProjects,
        }));
    };

    const handleDuplicate = async (projectId: string, projectName: string, thumbnail: string): Promise<void> => {
        if (projectSocket) {
            projectSocket.emit("v1:project:Duplicate", {
                userId,
                thumbnail,
                organization,
                projectUuid: generateUniqueId(),
                refProjectID: projectId,
                projectName,
            });
        }
        // 🔹 Refresh home & projects cache
        await fetchAllData();
    };

    // 🔹 Render Projects
    const renderProjects = () => {
        const key = Object.keys(projectsData)[0];
        const projectList = projectsData[key];

        if (!projectList?.length) {
            return <div className="empty-state">No projects found</div>;
        }

        return projectList.map((project) => (
            <DashboardCard
                key={project._id}
                projectName={project.projectName}
                thumbnail={project.thumbnail}
                projectId={project._id}
                createdBy={project.createdBy}
                createdAt={activeFolder === "trash" ? project.DeletedAt : project.createdAt}
                {...(activeFolder === "home" && {
                    handleDeleteProject: handleDelete,
                    handleDuplicateRecentProject: handleDuplicate,
                })}
                {...(activeSubFolder === "myProjects" && {
                    handleDeleteProject: handleDelete,
                    handleDuplicateWorkspaceProject: handleDuplicate,
                })}
                {...(activeSubFolder === "shared" && {
                    handleDuplicateWorkspaceProject: handleDuplicate,
                    active: "shared",
                })}
                {...(activeFolder === "trash" && {
                    handleRestoreProject: handleRestore,
                    handleTrashDeleteProject: async (id: string): Promise<void> => {
                        handlePermanentDelete(id);
                    },
                    active: "trash",
                })}
                openKebabProjectId={openKebabProjectId}
                setOpenKebabProjectId={setOpenKebabProjectId}
            />
        ));
    };

    return (
        <div className="dashboard-home-container">
            <DashboardNavBar
                page={activeFolder}
                {...(activeFolder === "trash"
                    ? { handleTrashSearch: handleSearch }
                    : {
                          handleProjectsSearch: handleSearch,
                          handleRecentProjectSearch: handleSearch,
                      })}
            />

            {activeFolder === "home" && <MarketPlaceBanner />}

            <div className="dashboard-container" style={{ height: "calc(100% - 87px)" }}>
                {activeFolder === "projects" && (
                    <div className="header-wrapper" style={{ display: "flex", gap: "7px" }}>
                        <button className={`header ${activeSubFolder === "myProjects" && "active"}`} onClick={() => setActiveSubFolder("myProjects")}>
                            My Projects
                        </button>
                        <button className={`header ${activeSubFolder === "shared" && "active"}`} onClick={() => setActiveSubFolder("shared")}>
                            Shared with me
                        </button>
                    </div>
                )}

                <div className="cards-container">{renderProjects()}</div>

                <ProjectSocketRes setIsSearchActive={setIsSearchActive} {...(activeFolder === "home" ? { setRecentProjects: setProjectsData } : { setWorkspaceProjects: setProjectsData })} />
            </div>
        </div>
    );
};

export default DashboardMain;
