import { FC, useState } from "react";
import { observer } from "mobx-react-lite";
import Link from "next/link";
import { useRouter } from "next/router";
import {
  AlertCircle,
  Archive,
  ArchiveRestoreIcon,
  FileText,
  Globe2,
  LinkIcon,
  Lock,
  Pencil,
  Star,
  Trash2,
} from "lucide-react";
// ui
import { CustomMenu, Tooltip } from "@plane/ui";
// components
import { CreateUpdatePageModal, DeletePageModal } from "components/pages";
// types
import { IIssueLabel } from "@plane/types";
// constants
import { EUserProjectRoles } from "constants/project";
import { PAGE_ARCHIVED, PAGE_FAVORITED, PAGE_RESTORED, PAGE_UNFAVORITED, PAGE_UPDATED } from "constants/event-tracker";
import { renderFormattedTime, renderFormattedDate } from "helpers/date-time.helper";
import { copyUrlToClipboard } from "helpers/string.helper";
import { useEventTracker, useMember, usePage, useUser } from "hooks/store";
import { useProjectPages } from "hooks/store/use-project-specific-pages";

export interface IPagesListItem {
  pageId: string;
  projectId: string;
}

export const PagesListItem: FC<IPagesListItem> = observer(({ pageId, projectId }: IPagesListItem) => {
  const projectPageStore = useProjectPages();
  // Now, I am observing only the projectPages, out of the projectPageStore.
  const { archivePage, restorePage } = projectPageStore;

  const pageStore = usePage(pageId);

  // router
  const router = useRouter();
  const { workspaceSlug } = router.query;
  // states
  const [createUpdatePageModal, setCreateUpdatePageModal] = useState(false);
  const [deletePageModal, setDeletePageModal] = useState(false);
  // store hooks
  const {
    currentUser,
    membership: { currentProjectRole },
  } = useUser();
  const {
    project: { getProjectMemberDetails },
  } = useMember();
  const { captureEvent } = useEventTracker();

  if (!pageStore) return null;

  const {
    archived_at,
    label_details,
    access,
    is_favorite,
    owned_by,
    name,
    created_at,
    updated_at,
    makePublic,
    makePrivate,
    addToFavorites,
    removeFromFavorites,
  } = pageStore;

  const handleCopyUrl = async (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    await copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/pages/${pageId}`);
  };

  const handleAddToFavorites = (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();
    addToFavorites().then(() => {
      captureEvent(PAGE_FAVORITED, {
        page_id: pageId,
        element: "Project pages page",
        state: "SUCCESS",
      });
    });
  };

  const handleRemoveFromFavorites = (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    removeFromFavorites().then(() => {
      captureEvent(PAGE_UNFAVORITED, {
        page_id: pageId,
        state: "SUCCESS",
      });
    });
  };

  const handleMakePublic = (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    makePublic().then(() => {
      captureEvent(PAGE_UPDATED, {
        page_id: pageId,
        access: "public",
        element: "Project pages page",
        state: "SUCCESS",
      });
    });
  };

  const handleMakePrivate = (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    makePrivate().then(() => {
      captureEvent(PAGE_UPDATED, {
        page_id: pageId,
        access: "private",
        element: "Project pages page",
        state: "SUCCESS",
      });
    });
  };

  const handleArchivePage = async (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    await archivePage(workspaceSlug as string, projectId as string, pageId as string).then(() => {
      captureEvent(PAGE_ARCHIVED, {
        page_id: pageId,
        access: access == 1 ? "private" : "public",
        element: "Project pages page",
        state: "SUCCESS",
      });
    });
  };

  const handleRestorePage = async (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    await restorePage(workspaceSlug as string, projectId as string, pageId as string).then(() => {
      captureEvent(PAGE_RESTORED, {
        page_id: pageId,
        access: access == 1 ? "private" : "public",
        element: "Project pages page",
        state: "SUCCESS",
      });
    });
  };

  const handleDeletePage = (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    setDeletePageModal(true);
  };

  const handleEditPage = (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    e.stopPropagation();

    setCreateUpdatePageModal(true);
  };

  const ownerDetails = getProjectMemberDetails(owned_by);
  const isCurrentUserOwner = owned_by === currentUser?.id;

  const userCanEdit =
    isCurrentUserOwner ||
    (currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole));
  const userCanChangeAccess = isCurrentUserOwner;
  const userCanArchive = isCurrentUserOwner || currentProjectRole === EUserProjectRoles.ADMIN;
  const userCanDelete = isCurrentUserOwner || currentProjectRole === EUserProjectRoles.ADMIN;
  const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;

  return (
    <>
      <CreateUpdatePageModal
        pageStore={pageStore}
        isOpen={createUpdatePageModal}
        handleClose={() => setCreateUpdatePageModal(false)}
        projectId={projectId}
      />
      <DeletePageModal isOpen={deletePageModal} onClose={() => setDeletePageModal(false)} pageId={pageId} />
      <li>
        <Link href={`/${workspaceSlug}/projects/${projectId}/pages/${pageId}`}>
          <div className="relative rounded p-3 md:p-4 text-custom-text-200 hover:bg-custom-background-80">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-2 overflow-hidden">
                <FileText className="h-4 w-4 shrink-0" />
                <p className="mr-2 truncate text-sm text-custom-text-100">{name}</p>
                {label_details.length > 0 &&
                  label_details.map((label: IIssueLabel) => (
                    <div
                      key={label.id}
                      className="group flex items-center gap-1 rounded-2xl border border-custom-border-200 px-2 py-0.5 text-xs"
                      style={{
                        backgroundColor: `${label?.color}20`,
                      }}
                    >
                      <span
                        className="h-1.5 w-1.5 flex-shrink-0 rounded-full"
                        style={{
                          backgroundColor: label?.color,
                        }}
                      />
                      {label.name}
                    </div>
                  ))}
              </div>
              <div className="flex items-center gap-2.5">
                {archived_at ? (
                  <Tooltip
                    tooltipContent={`Archived at ${renderFormattedTime(archived_at)} on ${renderFormattedDate(
                      archived_at
                    )}`}
                  >
                    <p className="text-sm text-custom-text-200">{renderFormattedTime(archived_at)}</p>
                  </Tooltip>
                ) : (
                  <Tooltip
                    tooltipContent={`Last updated at ${renderFormattedTime(updated_at)} on ${renderFormattedDate(
                      updated_at
                    )}`}
                  >
                    <p className="text-sm text-custom-text-200">{renderFormattedTime(updated_at)}</p>
                  </Tooltip>
                )}
                {isEditingAllowed && (
                  <Tooltip tooltipContent={`${is_favorite ? "Remove from favorites" : "Mark as favorite"}`}>
                    {is_favorite ? (
                      <button type="button" onClick={handleRemoveFromFavorites}>
                        <Star className="h-3.5 w-3.5 fill-orange-400 text-orange-400" />
                      </button>
                    ) : (
                      <button type="button" onClick={handleAddToFavorites}>
                        <Star className="h-3.5 w-3.5" />
                      </button>
                    )}
                  </Tooltip>
                )}
                {userCanChangeAccess && (
                  <Tooltip
                    tooltipContent={`${
                      access ? "This page is only visible to you" : "This page can be viewed by anyone in the project"
                    }`}
                  >
                    {access ? (
                      <button type="button" onClick={handleMakePublic}>
                        <Lock className="h-3.5 w-3.5" />
                      </button>
                    ) : (
                      <button type="button" onClick={handleMakePrivate}>
                        <Globe2 className="h-3.5 w-3.5" />
                      </button>
                    )}
                  </Tooltip>
                )}
                <Tooltip
                  position="top-right"
                  tooltipContent={`Created by ${ownerDetails?.member?.display_name} on ${renderFormattedDate(
                    created_at
                  )}`}
                >
                  <AlertCircle className="h-3.5 w-3.5" />
                </Tooltip>
                <CustomMenu placement="bottom-end" className="!-m-1" verticalEllipsis>
                  {archived_at ? (
                    <>
                      {userCanArchive && (
                        <CustomMenu.MenuItem onClick={handleRestorePage}>
                          <div className="flex items-center gap-2">
                            <ArchiveRestoreIcon className="h-3 w-3" />
                            <span>Restore page</span>
                          </div>
                        </CustomMenu.MenuItem>
                      )}
                      {userCanDelete && isEditingAllowed && (
                        <CustomMenu.MenuItem onClick={handleDeletePage}>
                          <div className="flex items-center gap-2">
                            <Trash2 className="h-3 w-3" />
                            <span>Delete page</span>
                          </div>
                        </CustomMenu.MenuItem>
                      )}
                    </>
                  ) : (
                    <>
                      {userCanEdit && isEditingAllowed && (
                        <CustomMenu.MenuItem onClick={handleEditPage}>
                          <div className="flex items-center gap-2">
                            <Pencil className="h-3 w-3" />
                            <span>Edit page</span>
                          </div>
                        </CustomMenu.MenuItem>
                      )}
                      {userCanArchive && isEditingAllowed && (
                        <CustomMenu.MenuItem onClick={handleArchivePage}>
                          <div className="flex items-center gap-2">
                            <Archive className="h-3 w-3" />
                            <span>Archive page</span>
                          </div>
                        </CustomMenu.MenuItem>
                      )}
                    </>
                  )}
                  <CustomMenu.MenuItem onClick={handleCopyUrl}>
                    <div className="flex items-center gap-2">
                      <LinkIcon className="h-3 w-3" />
                      <span>Copy page link</span>
                    </div>
                  </CustomMenu.MenuItem>
                </CustomMenu>
              </div>
            </div>
          </div>
        </Link>
      </li>
    </>
  );
});