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,
  useSocketStore,
} from "../../store/builder/store";
import OuterClick from "../../utils/outerClick";
import { KebabIcon } from "../icons/ExportCommonIcons";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
// 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>>;
  setRecentDuplicateData?: React.Dispatch<React.SetStateAction<object>>;
  setProjectDuplicateData?: React.Dispatch<React.SetStateAction<object>>;
  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,
  setRecentDuplicateData,
  setProjectDuplicateData,
  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);

  // 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 handleProjectName = useCallback(
    async (newName: string) => {
      setRenameValue(newName);
      if (!projectId) return;

      try {
        const projects = await getAllProjects(userId, organization);
        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 (handleDeleteProject?.(projectId) ??
            handleTrashDeleteProject?.(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) {
            setProjectDuplicateData?.({ projectId, projectName, thumbnail });
            await handleDuplicateWorkspaceProject(
              projectId,
              projectName,
              thumbnail,
              userId
            );
            if (active === "shared") {
              setActiveFolder?.("myProjects");
            }
          } else if (handleDuplicateRecentProject) {
            setRecentDuplicateData?.({
              projectId,
              projectName,
              thumbnail,
              userId,
            });
            await handleDuplicateRecentProject(
              projectId,
              projectName,
              thumbnail
            );
          }
          break;
      }
    },
    [
      projectId,
      projectName,
      thumbnail,
      userId,
      active,
      handleDeleteProject,
      handleTrashDeleteProject,
      handleRestoreProject,
      handleDuplicateWorkspaceProject,
      handleDuplicateRecentProject,
      setProjectName,
      setProjectDuplicateData,
      setRecentDuplicateData,
      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);
                }}
              >
                {option}
              </button>
            ))}
          </div>,
          document.body
        )}
    </div>
  );
};

export default DashboardCard;
