

import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { useRef, useState } from "react";
// buzzwareTech imports
import type { TLabelOperationsCallbacks } from "@/components/labels";
import {
    CreateUpdateLabelInline,
    DeleteLabelModal,
    ProjectSettingLabelGroup,
    ProjectSettingLabelItem,
} from "@/components/labels";
import { EUserPermissions, EUserPermissionsLevel } from "@buzzwaretech/constants";
import { useTranslation } from "@buzzwaretech/i18n";
import { Button } from "@buzzwaretech/propel/button";
import { EmptyStateCompact } from "@buzzwaretech/propel/empty-state";
import type { IIssueLabel } from "@buzzwaretech/types";
import { Loader } from "@buzzwaretech/ui";
// hooks
import { useLabel } from "@/hooks/store/use-label";
import { useUserPermissions } from "@/hooks/store/user";
// local imports
import { SettingsHeading } from "../settings/heading";

export const ProjectSettingsLabelList = observer(
  function ProjectSettingsLabelList() {
    // router
    const { workspaceSlug, projectId } = useParams();
    // refs
    const scrollToRef = useRef<HTMLDivElement>(null);
    // states
    const [showLabelForm, setLabelForm] = useState(false);
    const [isUpdating, setIsUpdating] = useState(false);
    const [selectDeleteLabel, setSelectDeleteLabel] =
      useState<IIssueLabel | null>(null);
    // buzzwareTech hooks
    const { t } = useTranslation();
    // store hooks
    const {
      projectLabels,
      updateLabelPosition,
      projectLabelsTree,
      createLabel,
      updateLabel,
    } = useLabel();
    const { allowPermissions } = useUserPermissions();
    // derived values
    const isEditable = allowPermissions(
      [EUserPermissions.ADMIN],
      EUserPermissionsLevel.PROJECT,
    );
    const labelOperationsCallbacks: TLabelOperationsCallbacks = {
      createLabel: (data: Partial<IIssueLabel>) =>
        createLabel(workspaceSlug?.toString(), projectId?.toString(), data),
      updateLabel: (labelId: string, data: Partial<IIssueLabel>) =>
        updateLabel(
          workspaceSlug?.toString(),
          projectId?.toString(),
          labelId,
          data,
        ),
    };

    const newLabel = () => {
      setIsUpdating(false);
      setLabelForm(true);
    };

    const onDrop = (
      draggingLabelId: string,
      droppedParentId: string | null,
      droppedLabelId: string | undefined,
      dropAtEndOfList: boolean,
    ) => {
      if (workspaceSlug && projectId) {
        updateLabelPosition(
          workspaceSlug?.toString(),
          projectId?.toString(),
          draggingLabelId,
          droppedParentId,
          droppedLabelId,
          dropAtEndOfList,
        );
        return;
      }
    };

    return (
      <>
        <DeleteLabelModal
          isOpen={!!selectDeleteLabel}
          data={selectDeleteLabel ?? null}
          onClose={() => setSelectDeleteLabel(null)}
        />
        <SettingsHeading
          title={t("project_settings.labels.heading")}
          description={t("project_settings.labels.description")}
          control={
            isEditable && (
              <Button variant="primary" size="lg" onClick={newLabel}>
                {t("common.add_label")}
              </Button>
            )
          }
        />
        <div className="mt-6 w-full">
          {showLabelForm && (
            <div className="my-2 w-full rounded-sm border border-subtle px-3.5 py-2">
              <CreateUpdateLabelInline
                labelForm={showLabelForm}
                setLabelForm={setLabelForm}
                isUpdating={isUpdating}
                labelOperationsCallbacks={labelOperationsCallbacks}
                ref={scrollToRef}
                onClose={() => {
                  setLabelForm(false);
                  setIsUpdating(false);
                }}
              />
            </div>
          )}
          {projectLabels ? (
            projectLabels.length === 0 && !showLabelForm ? (
              <EmptyStateCompact
                assetKey="label"
                assetClassName="size-20"
                title={t("settings_empty_state.labels.title")}
                description={t("settings_empty_state.labels.description")}
                actions={[
                  {
                    label: t("settings_empty_state.labels.cta_primary"),
                    onClick: () => {
                      newLabel();
                    },
                  },
                ]}
                align="start"
                rootClassName="py-20"
              />
            ) : (
              projectLabelsTree?.map((label, index) => {
                if (label.children && label.children.length) {
                  return (
                    <ProjectSettingLabelGroup
                      key={label.id}
                      label={label}
                      labelChildren={label.children || []}
                      handleLabelDelete={(label: IIssueLabel) =>
                        setSelectDeleteLabel(label)
                      }
                      isUpdating={isUpdating}
                      setIsUpdating={setIsUpdating}
                      isLastChild={index === projectLabelsTree.length - 1}
                      onDrop={onDrop}
                      isEditable={isEditable}
                      labelOperationsCallbacks={labelOperationsCallbacks}
                    />
                  );
                }
                return (
                  <ProjectSettingLabelItem
                    label={label}
                    key={label.id}
                    setIsUpdating={setIsUpdating}
                    handleLabelDelete={(label) => setSelectDeleteLabel(label)}
                    isChild={false}
                    isLastChild={index === projectLabelsTree.length - 1}
                    onDrop={onDrop}
                    isEditable={isEditable}
                    labelOperationsCallbacks={labelOperationsCallbacks}
                  />
                );
              })
            )
          ) : (
            !showLabelForm && (
              <Loader className="space-y-5">
                <Loader.Item height="42px" />
                <Loader.Item height="42px" />
                <Loader.Item height="42px" />
                <Loader.Item height="42px" />
              </Loader>
            )
          )}
        </div>
      </>
    );
  },
);
