"use client";

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

import { useMemo } from "react";
import Link from "next/link";
import { Menu } from "@headlessui/react";
import { observer } from "mobx-react";
import { useParams, usePathname } from "next/navigation";
import useSWR from "swr";
import {
  EUserPermissions,
  EUserPermissionsLevel,
  WORKSPACE_SIDEBAR_DYNAMIC_NAVIGATION_ITEMS_LINKS,
  WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS,
  WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS_LINKS,
} from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { InboxIcon, PlusIcon, ProjectIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { copyUrlToClipboard, joinUrlPath } from "@plane/utils";
import { TopNavPowerK } from "@/components/navigation";
import { useCommandPalette } from "@/hooks/store/use-command-palette";
import { useProject } from "@/hooks/store/use-project";
import { useWorkspaceNotifications } from "@/hooks/store/notifications";
import { useUser, useUserPermissions } from "@/hooks/store/user";
import {
  usePersonalNavigationPreferences,
  useWorkspaceNavigationPreferences,
} from "@/hooks/use-navigation-preferences";
import { SidebarProjectsListItem } from "@/components/workspace/sidebar/projects-list-item";
import { UserMenuRoot } from "@/components/workspace/sidebar/user-menu-root";
import { WorkspaceMenuRoot } from "@/components/workspace/sidebar/workspace-menu-root";
import { getSidebarNavigationItemIcon } from "@/plane-web/components/workspace/sidebar/helper";

type TToolbarItem = {
  key: string;
  href?: string;
  labelTranslationKey: string;
  active: boolean;
  icon: React.ReactNode;
  onClick?: () => void;
};

const ToolbarIconLink = ({ item }: { item: TToolbarItem }) => {
  const { t } = useTranslation();

  return (
    <Tooltip tooltipContent={t(item.labelTranslationKey)} position="bottom">
      <Link
        href={item.href ?? "#"}
        className="nodedc-toolbar-icon-button flex h-8 w-8 items-center justify-center"
        data-active={item.active}
        aria-label={t(item.labelTranslationKey)}
      >
        <span className="nodedc-toolbar-icon-active-dot">{item.icon}</span>
      </Link>
    </Tooltip>
  );
};

const ToolbarIconButton = ({
  label,
  active = false,
  children,
  onClick,
  disabled = false,
}: {
  label: string;
  active?: boolean;
  children: React.ReactNode;
  onClick?: () => void;
  disabled?: boolean;
}) => (
  <Tooltip tooltipContent={label} position="bottom">
    <button
      type="button"
      className="nodedc-toolbar-icon-button flex h-8 w-8 items-center justify-center"
      data-active={active}
      aria-label={label}
      onClick={onClick}
      disabled={disabled}
    >
      <span className="nodedc-toolbar-icon-active-dot">{children}</span>
    </button>
  </Tooltip>
);

const ProjectsToolbarMenu = observer(function ProjectsToolbarMenu() {
  const { t } = useTranslation();
  const pathname = usePathname();
  const { workspaceSlug } = useParams();
  const { joinedProjectIds } = useProject();

  const handleCopyText = (projectId: string) =>
    copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/issues`).then(() => {
      setToast({
        type: TOAST_TYPE.SUCCESS,
        title: t("link_copied"),
        message: t("project_link_copied_to_clipboard"),
      });
    });

  return (
    <Menu as="div" className="relative">
      <Menu.Button
        type="button"
        title={t("workspace_sidebar.projects.main")}
        className="nodedc-toolbar-icon-button grid h-8 w-8 place-items-center"
        aria-label={t("workspace_sidebar.projects.main")}
      >
        <span
          className={`nodedc-toolbar-icon-active-dot ${
            pathname.includes("/projects/") ? "bg-[rgb(var(--nodedc-accent-rgb))] text-[#0b1117]" : ""
          }`}
        >
          <ProjectIcon className="size-4" />
        </span>
      </Menu.Button>

      <Menu.Items className="absolute top-full -right-2 z-[170] mt-2 origin-top-right">
        <div className="nodedc-glass-modal nodedc-glass-popup-surface flex max-h-[70vh] min-w-[26rem] flex-col overflow-hidden rounded-[1.5rem] border-0 p-2 shadow-none outline-none">
          <div className="vertical-scrollbar scrollbar-sm flex max-h-[70vh] flex-col gap-0.5 overflow-y-auto pr-1">
            {joinedProjectIds.map((projectId, index) => (
              <SidebarProjectsListItem
                key={projectId}
                projectId={projectId}
                handleCopyText={() => handleCopyText(projectId)}
                projectListType="JOINED"
                disableDrag
                disableDrop
                isLastChild={index === joinedProjectIds.length - 1}
              />
            ))}
          </div>
        </div>
      </Menu.Items>
    </Menu>
  );
});

export const ProjectShellTopToolbar = observer(function ProjectShellTopToolbar() {
  const { t } = useTranslation();
  const pathname = usePathname();
  const { workspaceSlug } = useParams();
  const { toggleCreateIssueModal } = useCommandPalette();
  const { joinedProjectIds } = useProject();
  const { data: currentUser } = useUser();
  const { allowPermissions } = useUserPermissions();
  const { unreadNotificationsCount, getUnreadNotificationsCount } = useWorkspaceNotifications();
  const { preferences: personalPreferences } = usePersonalNavigationPreferences();
  const { preferences: workspacePreferences } = useWorkspaceNavigationPreferences();

  const canCreateIssue = allowPermissions(
    [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
    EUserPermissionsLevel.WORKSPACE
  );

  useSWR(
    workspaceSlug ? "WORKSPACE_UNREAD_NOTIFICATION_COUNT" : null,
    workspaceSlug ? () => getUnreadNotificationsCount(workspaceSlug.toString()) : null
  );

  const isMentionsEnabled = unreadNotificationsCount.mention_unread_notifications_count > 0;
  const totalNotifications = isMentionsEnabled
    ? unreadNotificationsCount.mention_unread_notifications_count
    : unreadNotificationsCount.total_unread_notifications_count;

  const primaryItems = useMemo(() => {
    const items = [...WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS_LINKS];
    const personalItems: Array<(typeof items)[0] & { sort_order: number }> = [];

    const stickiesItem = WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS["stickies"];
    if (personalPreferences.items.stickies?.enabled && stickiesItem) {
      personalItems.push({
        ...stickiesItem,
        sort_order: personalPreferences.items.stickies.sort_order,
      });
    }
    if (personalPreferences.items.your_work?.enabled && WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS["your-work"]) {
      personalItems.push({
        ...WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS["your-work"],
        sort_order: personalPreferences.items.your_work.sort_order,
      });
    }
    if (personalPreferences.items.drafts?.enabled && WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS["drafts"]) {
      personalItems.push({
        ...WORKSPACE_SIDEBAR_STATIC_NAVIGATION_ITEMS["drafts"],
        sort_order: personalPreferences.items.drafts.sort_order,
      });
    }

    personalItems.sort((a, b) => a.sort_order - b.sort_order);

    return [...items, ...personalItems].map((item) => {
      const href =
        item.key === "your_work" && currentUser?.id
          ? joinUrlPath(workspaceSlug?.toString() ?? "", item.href, currentUser.id)
          : joinUrlPath(workspaceSlug?.toString() ?? "", item.href);

      return {
        key: item.key,
        href,
        labelTranslationKey: item.labelTranslationKey,
        active: item.highlight(pathname, href),
        icon: getSidebarNavigationItemIcon(item.key),
      } satisfies TToolbarItem;
    });
  }, [currentUser?.id, pathname, personalPreferences, workspaceSlug]);

  const secondaryItems = useMemo(
    () =>
      WORKSPACE_SIDEBAR_DYNAMIC_NAVIGATION_ITEMS_LINKS.map((item) => {
        const href = joinUrlPath(workspaceSlug?.toString() ?? "", item.href);
        const preference = workspacePreferences.items[item.key];

        return {
          key: item.key,
          href,
          labelTranslationKey: item.labelTranslationKey,
          active: item.highlight(pathname, href),
          icon: getSidebarNavigationItemIcon(item.key),
          sort_order: preference ? preference.sort_order : 0,
        };
      }).sort((a, b) => a.sort_order - b.sort_order),
    [pathname, workspacePreferences, workspaceSlug]
  );

  return (
    <div className="z-20 w-full flex-shrink-0 px-4 pt-4 pb-3">
      <div className="nodedc-glass-modal flex w-full flex-wrap items-center justify-between gap-4 rounded-[1.6rem] px-4 py-3">
        <div className="flex min-w-0 items-center gap-3">
          <div className="nodedc-toolbar-group relative flex items-center gap-1 overflow-visible">
            <ToolbarIconButton
              label={t("app_header.add_task")}
              onClick={() => toggleCreateIssueModal(true)}
              disabled={!canCreateIssue || joinedProjectIds.length === 0}
            >
              <PlusIcon className="size-4" />
            </ToolbarIconButton>
            <TopNavPowerK variant="sidebar" />
            <Tooltip tooltipContent={t("notification.label")} position="bottom">
              <Link
                href={`/${workspaceSlug?.toString()}/notifications/`}
                className="nodedc-toolbar-icon-button relative flex h-8 w-8 items-center justify-center"
                data-active={pathname.includes("/notifications/")}
                aria-label={t("notification.label")}
              >
                <span className="nodedc-toolbar-icon-active-dot">
                  <InboxIcon className="size-4" />
                </span>
                {totalNotifications > 0 && (
                  <span className="absolute top-1.5 right-1.5 size-2 rounded-full bg-danger-primary" />
                )}
              </Link>
            </Tooltip>
            <UserMenuRoot variant="toolbar" />
            <WorkspaceMenuRoot variant="toolbar" />
          </div>
        </div>

        <div className="flex min-w-0 items-center justify-end gap-3">
          <div className="nodedc-toolbar-group flex items-center gap-1">
            {primaryItems.map((item) => (
              <ToolbarIconLink key={item.key} item={item} />
            ))}
          </div>

          <div className="nodedc-toolbar-group relative flex items-center gap-1 overflow-visible">
            <ProjectsToolbarMenu />
            {secondaryItems.map((item) => (
              <ToolbarIconLink key={item.key} item={item} />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
});
