

import { observer } from "mobx-react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
// BuzzwareTech imports
import { TOAST_TYPE, setToast } from "@buzzwaretech/propel/toast";
import type { IModule } from "@buzzwaretech/types";
import { EModalPosition, EModalWidth, ModalCore } from "@buzzwaretech/ui";
// components
import { ModuleForm } from "@/components/modules";
// hooks
import { useModule } from "@/hooks/store/use-module";
import { useProject } from "@/hooks/store/use-project";
import useKeypress from "@/hooks/use-keypress";
import { usePlatformOS } from "@/hooks/use-platform-os";

type Props = {
  isOpen: boolean;
  onClose: () => void;
  data?: IModule;
  workspaceSlug: string;
  projectId: string;
};

const defaultValues: Partial<IModule> = {
  name: "",
  description: "",
  status: "backlog",
  lead_id: null,
  member_ids: [],
};

export const CreateUpdateModuleModal = observer(
  function CreateUpdateModuleModal(props: Props) {
    const { isOpen, onClose, data, workspaceSlug, projectId } = props;
    // states
    const [activeProject, setActiveProject] = useState<string | null>(null);
    // store hooks
    const { workspaceProjectIds } = useProject();
    const { createModule, updateModuleDetails } = useModule();
    const { isMobile } = usePlatformOS();

    const handleClose = () => {
      reset(defaultValues);
      onClose();
    };

    const { reset } = useForm<IModule>({
      defaultValues,
    });

    const handleCreateModule = async (payload: Partial<IModule>) => {
      if (!workspaceSlug || !projectId) return;

      const selectedProjectId = payload.project_id ?? projectId.toString();
      await createModule(workspaceSlug.toString(), selectedProjectId, payload)
        .then((_res) => {
          handleClose();
          setToast({
            type: TOAST_TYPE.SUCCESS,
            title: "Success!",
            message: "Module created successfully.",
          });
        })
        .catch((err) => {
          setToast({
            type: TOAST_TYPE.ERROR,
            title: "Error!",
            message:
              err?.detail ??
              err?.error ??
              "Module could not be created. Please try again.",
          });
        });
    };

    const handleUpdateModule = async (payload: Partial<IModule>) => {
      if (!workspaceSlug || !projectId || !data) return;

      const selectedProjectId = payload.project_id ?? projectId.toString();
      await updateModuleDetails(
        workspaceSlug.toString(),
        selectedProjectId,
        data.id,
        payload,
      )
        .then((_res) => {
          handleClose();

          setToast({
            type: TOAST_TYPE.SUCCESS,
            title: "Success!",
            message: "Module updated successfully.",
          });
        })
        .catch((err) => {
          setToast({
            type: TOAST_TYPE.ERROR,
            title: "Error!",
            message:
              err?.detail ??
              err?.error ??
              "Module could not be updated. Please try again.",
          });
        });
    };

    const handleFormSubmit = async (formData: Partial<IModule>) => {
      if (!workspaceSlug || !projectId) return;

      const payload: Partial<IModule> = {
        ...formData,
      };
      if (!data) await handleCreateModule(payload);
      else await handleUpdateModule(payload);
    };

    useEffect(() => {
      // if modal is closed, reset active project to null
      // and return to avoid activeProject being set to some other project
      if (!isOpen) {
        setActiveProject(null);
        return;
      }

      // if data is present, set active project to the project of the
      // issue. This has more priority than the project in the url.
      if (data && data.project_id) {
        setActiveProject(data.project_id);
        return;
      }

      // if data is not present, set active project to the project
      // in the url. This has the least priority.
      if (
        workspaceProjectIds &&
        workspaceProjectIds.length > 0 &&
        !activeProject
      )
        setActiveProject(projectId ?? workspaceProjectIds?.[0] ?? null);
    }, [activeProject, data, projectId, workspaceProjectIds, isOpen]);

    useKeypress("Escape", () => {
      if (isOpen) handleClose();
    });

    return (
      <ModalCore
        isOpen={isOpen}
        position={EModalPosition.TOP}
        width={EModalWidth.XXL}
      >
        <ModuleForm
          handleFormSubmit={handleFormSubmit}
          handleClose={handleClose}
          status={data ? true : false}
          projectId={activeProject ?? ""}
          setActiveProject={setActiveProject}
          data={data}
          isMobile={isMobile}
        />
      </ModalCore>
    );
  },
);
