/**
 * Copyright (c) 2023-present Pi Dash Software, Inc. and contributors
 * SPDX-License-Identifier: AGPL-3.0-only
 * See the LICENSE file for details.
 */

import { useCallback, useRef, useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// pi dash imports
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@pi-dash/constants";
import { useTranslation } from "@pi-dash/i18n";
import { EmptyStateCompact } from "@pi-dash/propel/empty-state";
import { PlusIcon, SearchIcon } from "@pi-dash/propel/icons";
import { TOAST_TYPE, setToast } from "@pi-dash/propel/toast";
import { Tooltip } from "@pi-dash/propel/tooltip";
import { copyUrlToClipboard, orderJoinedProjects } from "@pi-dash/utils";
// components
import { CreateProjectModal } from "@/components/project/create-project-modal";
import { SidebarProjectsListItem } from "@/components/workspace/sidebar/projects-list-item";
// hooks
import { useAppTheme } from "@/hooks/store/use-app-theme";
import { useProject } from "@/hooks/store/use-project";
import { useUserPermissions } from "@/hooks/store/user";
import type { TProject } from "@/pi-dash-web/types";
import { ExtendedSidebarWrapper } from "./extended-sidebar-wrapper";

export const ExtendedProjectSidebar = observer(function ExtendedProjectSidebar() {
  // refs
  const extendedProjectSidebarRef = useRef<HTMLDivElement | null>(null);
  const [searchQuery, setSearchQuery] = useState<string>("");
  // states
  const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
  // routers
  const { workspaceSlug } = useParams();
  // store hooks
  const { t } = useTranslation();
  const { isExtendedProjectSidebarOpened, toggleExtendedProjectSidebar } = useAppTheme();
  const { getPartialProjectById, joinedProjectIds: joinedProjects, updateProjectView } = useProject();
  const { allowPermissions } = useUserPermissions();

  const handleOnProjectDrop = (
    sourceId: string | undefined,
    destinationId: string | undefined,
    shouldDropAtEnd: boolean
  ) => {
    if (!sourceId || !destinationId || !workspaceSlug) return;
    if (sourceId === destinationId) return;

    const joinedProjectsList: TProject[] = [];
    joinedProjects.map((projectId) => {
      const projectDetails = getPartialProjectById(projectId);
      if (projectDetails) joinedProjectsList.push(projectDetails);
    });

    const sourceIndex = joinedProjects.indexOf(sourceId);
    const destinationIndex = shouldDropAtEnd ? joinedProjects.length : joinedProjects.indexOf(destinationId);

    if (joinedProjectsList.length <= 0) return;

    const updatedSortOrder = orderJoinedProjects(sourceIndex, destinationIndex, sourceId, joinedProjectsList);
    if (updatedSortOrder != undefined)
      updateProjectView(workspaceSlug.toString(), sourceId, { sort_order: updatedSortOrder }).catch(() => {
        setToast({
          type: TOAST_TYPE.ERROR,
          title: t("Error"),
          message: t("Something went wrong"),
        });
      });
  };

  // filter projects based on search query
  const filteredProjects = joinedProjects.filter((projectId) => {
    const project = getPartialProjectById(projectId);
    if (!project) return false;
    return project.name.toLowerCase().includes(searchQuery.toLowerCase()) || project.identifier.includes(searchQuery);
  });

  // auth
  const isAuthorizedUser = allowPermissions(
    [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
    EUserPermissionsLevel.WORKSPACE
  );

  const handleClose = useCallback(() => toggleExtendedProjectSidebar(false), [toggleExtendedProjectSidebar]);

  const handleCopyText = async (projectId: string) => {
    await copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/issues`);
    setToast({
      type: TOAST_TYPE.SUCCESS,
      title: t("Link copied"),
      message: t("Project link copied to clipboard"),
    });
  };
  return (
    <>
      {workspaceSlug && (
        <CreateProjectModal
          isOpen={isProjectModalOpen}
          onClose={() => setIsProjectModalOpen(false)}
          setToFavorite={false}
          workspaceSlug={workspaceSlug.toString()}
        />
      )}
      <ExtendedSidebarWrapper
        isExtendedSidebarOpened={!!isExtendedProjectSidebarOpened}
        extendedSidebarRef={extendedProjectSidebarRef}
        handleClose={handleClose}
        excludedElementId="extended-project-sidebar-toggle"
        className="px-0"
      >
        <div className="sticky top-4 flex w-full flex-col gap-1 px-4">
          <div className="flex items-center justify-between">
            <span className="py-1.5 text-13 font-semibold text-tertiary">Projects</span>
            {isAuthorizedUser && (
              <Tooltip tooltipHeading={t("Create project")} tooltipContent="">
                <button
                  type="button"
                  data-ph-element={PROJECT_TRACKER_ELEMENTS.EXTENDED_SIDEBAR_ADD_BUTTON}
                  className="flex-shrink-0 rounded-sm p-0.5 text-tertiary transition-colors hover:bg-layer-1 hover:text-secondary"
                  onClick={() => {
                    setIsProjectModalOpen(true);
                  }}
                >
                  <PlusIcon className="size-3" />
                </button>
              </Tooltip>
            )}
          </div>
          <div className="ml-auto flex w-full items-center gap-1.5 rounded-md border border-subtle bg-surface-1 px-2.5 py-1">
            <SearchIcon className="h-3.5 w-3.5 text-placeholder" />
            <input
              className="w-full max-w-[234px] border-none bg-transparent text-13 outline-none placeholder:text-placeholder"
              placeholder={t("Search")}
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
            />
          </div>
        </div>
        {filteredProjects.length === 0 ? (
          <div className="mt-4 flex flex-col items-center p-10">
            <EmptyStateCompact
              title={t("No matching results.")}
              description={t("No results found. Try adjusting your search terms.")}
              assetKey="search"
              assetClassName="size-20"
              align="center"
            />
          </div>
        ) : (
          <div className="vertical-scrollbar mt-4 flex scrollbar-sm flex-grow flex-col gap-0.5 overflow-x-hidden overflow-y-auto pr-2 pl-9">
            {filteredProjects.map((projectId, index) => (
              <SidebarProjectsListItem
                key={projectId}
                projectId={projectId}
                handleCopyText={() => handleCopyText(projectId)}
                projectListType={"JOINED"}
                disableDrag={false}
                disableDrop={false}
                isLastChild={index === filteredProjects.length - 1}
                handleOnProjectDrop={handleOnProjectDrop}
                renderInExtendedSidebar
              />
            ))}
          </div>
        )}
      </ExtendedSidebarWrapper>
    </>
  );
});
