import { useState } from "react";

import { useRouter } from "next/router";

// react-beautiful-dnd
import StrictModeDroppable from "components/dnd/StrictModeDroppable";
import { Draggable } from "react-beautiful-dnd";
// components
import { BoardHeader, SingleBoardIssue, BoardInlineCreateIssueForm } from "components/core";
// ui
import { CustomMenu } from "components/ui";
// icons
import { PlusIcon } from "@heroicons/react/24/outline";
// helpers
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
// types
import { ICurrentUserResponse, IIssue, IIssueViewProps, IState, UserAuth } from "types";

type Props = {
  addIssueToGroup: () => void;
  currentState?: IState | null;
  disableUserActions: boolean;
  disableAddIssueOption?: boolean;
  dragDisabled: boolean;
  groupTitle: string;
  handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void;
  handleDraftIssueAction?: (issue: IIssue, action: "edit" | "delete") => void;
  handleTrashBox: (isDragging: boolean) => void;
  openIssuesListModal?: (() => void) | null;
  handleMyIssueOpen?: (issue: IIssue) => void;
  removeIssue: ((bridgeId: string, issueId: string) => void) | null;
  user: ICurrentUserResponse | undefined;
  userAuth: UserAuth;
  viewProps: IIssueViewProps;
};

export const SingleBoard: React.FC<Props> = (props) => {
  const {
    addIssueToGroup,
    currentState,
    groupTitle,
    disableUserActions,
    disableAddIssueOption = false,
    dragDisabled,
    handleIssueAction,
    handleDraftIssueAction,
    handleTrashBox,
    openIssuesListModal,
    handleMyIssueOpen,
    removeIssue,
    user,
    userAuth,
    viewProps,
  } = props;

  // collapse/expand
  const [isCollapsed, setIsCollapsed] = useState(true);

  const [isInlineCreateIssueFormOpen, setIsInlineCreateIssueFormOpen] = useState(false);

  const { displayFilters, groupedIssues } = viewProps;

  const router = useRouter();
  const { cycleId, moduleId } = router.query;

  const isMyIssuesPage = router.pathname.split("/")[3] === "my-issues";
  const isProfileIssuesPage = router.pathname.split("/")[2] === "profile";
  const isDraftIssuesPage = router.pathname.split("/")[4] === "draft-issues";

  const type = cycleId ? "cycle" : moduleId ? "module" : "issue";

  // Check if it has at least 4 tickets since it is enough to accommodate the Calendar height
  const issuesLength = groupedIssues?.[groupTitle].length;
  const hasMinimumNumberOfCards = issuesLength ? issuesLength >= 4 : false;

  const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disableUserActions;

  const scrollToBottom = () => {
    const boardListElement = document.getElementById(`board-list-${groupTitle}`);

    // timeout is needed because the animation
    // takes time to complete & we can scroll only after that
    const timeoutId = setTimeout(() => {
      if (boardListElement)
        boardListElement.scrollBy({
          top: boardListElement.scrollHeight,
          left: 0,
          behavior: "smooth",
        });
      clearTimeout(timeoutId);
    }, 10);
  };

  const onCreateClick = () => {
    setIsInlineCreateIssueFormOpen(true);
    scrollToBottom();
  };

  return (
    <div className={`flex-shrink-0 ${!isCollapsed ? "" : "flex h-full flex-col w-96"}`}>
      <BoardHeader
        addIssueToGroup={addIssueToGroup}
        currentState={currentState}
        groupTitle={groupTitle}
        isCollapsed={isCollapsed}
        setIsCollapsed={setIsCollapsed}
        disableUserActions={disableUserActions}
        disableAddIssue={disableAddIssueOption}
        viewProps={viewProps}
      />
      {isCollapsed && (
        <StrictModeDroppable key={groupTitle} droppableId={groupTitle}>
          {(provided, snapshot) => (
            <div
              className={`relative h-full ${
                displayFilters?.order_by !== "sort_order" && snapshot.isDraggingOver
                  ? "bg-custom-background-100/20"
                  : ""
              } ${!isCollapsed ? "hidden" : "flex flex-col"}`}
              ref={provided.innerRef}
              {...provided.droppableProps}
            >
              {displayFilters?.order_by !== "sort_order" && (
                <>
                  <div
                    className={`absolute ${
                      snapshot.isDraggingOver ? "block" : "hidden"
                    } pointer-events-none top-0 left-0 z-[99] h-full w-full bg-custom-background-90 opacity-50`}
                  />
                  <div
                    className={`absolute ${
                      snapshot.isDraggingOver ? "block" : "hidden"
                    } pointer-events-none top-1/2 left-1/2 z-[99] -translate-y-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-custom-background-100 p-2 text-xs`}
                  >
                    This board is ordered by{" "}
                    {replaceUnderscoreIfSnakeCase(
                      displayFilters?.order_by
                        ? displayFilters?.order_by[0] === "-"
                          ? displayFilters?.order_by.slice(1)
                          : displayFilters?.order_by
                        : "created_at"
                    )}
                  </div>
                </>
              )}
              <div
                id={`board-list-${groupTitle}`}
                className={`pt-3 ${
                  hasMinimumNumberOfCards ? "overflow-hidden overflow-y-scroll" : ""
                } `}
              >
                {groupedIssues?.[groupTitle].map((issue, index) => (
                  <Draggable
                    key={issue.id}
                    draggableId={issue.id}
                    index={index}
                    isDragDisabled={isNotAllowed || dragDisabled}
                  >
                    {(provided, snapshot) => (
                      <SingleBoardIssue
                        key={index}
                        provided={provided}
                        snapshot={snapshot}
                        type={type}
                        index={index}
                        issue={issue}
                        projectId={issue.project_detail.id}
                        groupTitle={groupTitle}
                        editIssue={() => handleIssueAction(issue, "edit")}
                        makeIssueCopy={() => handleIssueAction(issue, "copy")}
                        handleDeleteIssue={() => handleIssueAction(issue, "delete")}
                        handleDraftIssueEdit={
                          handleDraftIssueAction
                            ? () => handleDraftIssueAction(issue, "edit")
                            : undefined
                        }
                        handleDraftIssueDelete={() =>
                          handleDraftIssueAction
                            ? handleDraftIssueAction(issue, "delete")
                            : undefined
                        }
                        handleTrashBox={handleTrashBox}
                        handleMyIssueOpen={handleMyIssueOpen}
                        removeIssue={() => {
                          if (removeIssue && issue.bridge_id)
                            removeIssue(issue.bridge_id, issue.id);
                        }}
                        disableUserActions={disableUserActions}
                        user={user}
                        userAuth={userAuth}
                        viewProps={viewProps}
                      />
                    )}
                  </Draggable>
                ))}
                <span
                  style={{
                    display: displayFilters?.order_by === "sort_order" ? "inline" : "none",
                  }}
                >
                  <>{provided.placeholder}</>
                </span>

                <BoardInlineCreateIssueForm
                  isOpen={isInlineCreateIssueFormOpen}
                  handleClose={() => setIsInlineCreateIssueFormOpen(false)}
                  onSuccess={() => scrollToBottom()}
                  prePopulatedData={{
                    ...(cycleId && { cycle: cycleId.toString() }),
                    ...(moduleId && { module: moduleId.toString() }),
                    [displayFilters?.group_by! === "labels"
                      ? "labels_list"
                      : displayFilters?.group_by!]:
                      displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle,
                  }}
                />
              </div>
              {displayFilters?.group_by !== "created_by" && (
                <div>
                  {type === "issue"
                    ? !disableAddIssueOption && (
                        <button
                          type="button"
                          className="flex items-center gap-2 font-medium text-custom-primary outline-none p-1"
                          onClick={() => {
                            if (isDraftIssuesPage || isMyIssuesPage || isProfileIssuesPage) {
                              addIssueToGroup();
                            } else onCreateClick();
                          }}
                        >
                          <PlusIcon className="h-4 w-4" />
                          Add Issue
                        </button>
                      )
                    : !disableUserActions && (
                        <CustomMenu
                          customButton={
                            <button
                              type="button"
                              className="flex items-center gap-2 font-medium text-custom-primary outline-none whitespace-nowrap"
                            >
                              <PlusIcon className="h-4 w-4" />
                              Add Issue
                            </button>
                          }
                          position="left"
                          noBorder
                        >
                          <CustomMenu.MenuItem onClick={() => onCreateClick()}>
                            Create new
                          </CustomMenu.MenuItem>
                          {openIssuesListModal && (
                            <CustomMenu.MenuItem onClick={openIssuesListModal}>
                              Add an existing issue
                            </CustomMenu.MenuItem>
                          )}
                        </CustomMenu>
                      )}
                </div>
              )}
            </div>
          )}
        </StrictModeDroppable>
      )}
    </div>
  );
};