"use client";

import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Grid from "@mui/material/Grid";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import { useTranslation } from "react-i18next";
import TransferList from "../TransferList";
import Button from "@mui/material/Button";
import Check from "@mui/icons-material/Check";
import Close from "@mui/icons-material/Close";
import { useRouter } from "next/navigation";
import React from "react";
import Stack from "@mui/material/Stack";
import { Task, TaskTemplate } from "@/app/api/tasks";
import {
  NewTaskTemplateFormInputs,
  saveTaskTemplate,
} from "@/app/api/tasks/actions";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { errorDialog, submitDialog, successDialog } from "../Swal/CustomAlerts";
import { Grade } from "@/app/api/grades";
import { intersectionWith, isEmpty } from "lodash";
import ResourceAllocationWrapper from "./ResourceAllocation";

interface Props {
  tasks: Task[];
  defaultInputs?: NewTaskTemplateFormInputs;
  grades: Grade[]
}



const CreateTaskTemplate: React.FC<Props> = ({ tasks, defaultInputs, grades }) => {
  const { t } = useTranslation();

  const router = useRouter();
  const handleCancel = () => {
    router.back();
  };

  const items = React.useMemo(
    () =>
      tasks.map((task) => ({
        id: task.id,
        label: task.name,
        group: task.taskGroup || undefined,
      })),
    [tasks],
  );

  const [serverError, setServerError] = React.useState("");

  const formProps = useForm<NewTaskTemplateFormInputs>({
    defaultValues: {
      taskGroups: {},
      ...defaultInputs,

      manhourPercentageByGrade: isEmpty(defaultInputs?.manhourPercentageByGrade)
        ? grades.reduce((acc, grade) => {
          return { ...acc, [grade.id]: 100 / grades.length };
        }, {})
        : defaultInputs?.manhourPercentageByGrade,
    }
  });

  const currentTaskGroups = formProps.watch("taskGroups");
  const currentTaskIds = Object.values(currentTaskGroups).reduce<Task["id"][]>(
    (acc, group) => {
      return [...acc, ...group.taskIds];
    },
    [],
  );
  const selectedItems = React.useMemo(() => {
    return intersectionWith(
      tasks,
      currentTaskIds,
      (task, taskId) => task.id === taskId,
    ).map((t) => ({ id: t.id, label: t.name, group: t.taskGroup }));
  }, [currentTaskIds, tasks]);

  const onSubmit: SubmitHandler<NewTaskTemplateFormInputs> = React.useCallback(
    async (data) => {
      try {
        setServerError("");

        let hasErrors = false

        // check the manhour allocation by stage by grade -> total = 100?
        const taskGroupKeys = Object.keys(data.taskGroups)
        if (taskGroupKeys.filter(k => data.taskGroups[k as any].percentAllocation < 0).length > 0 ||
          taskGroupKeys.reduce((acc, value) => acc + data.taskGroups[value as any].percentAllocation, 0) !== 100) {
          formProps.setError("taskGroups", { message: "Task Groups value is not invalid", type: "invalid" })
          hasErrors = true
        }

        if (hasErrors) return false

        submitDialog(async () => {
          const response = await saveTaskTemplate(data);

          if (response.message === "Success") {
            successDialog(t("Submit Success"), t).then(() => {
              router.replace("/tasks");
            })
          } else {
            errorDialog(t("Submit Fail"), t).then(() => {
              formProps.setError("code", { message: response.message, type: "custom" })
              return false
            })
          }
        }, t)
      } catch (e) {
        setServerError(t("An error has occurred. Please try again later."));
      }
    },
    [router, t],
  );

  return (
    <>
      <FormProvider {...formProps}>
        <Stack component="form" onSubmit={formProps.handleSubmit(onSubmit)} gap={2}>
          {/* Task List Setup */}
          <Card>
            <CardContent sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
              <Typography variant="overline">{t("Task List Setup")}</Typography>
              <Grid
                container
                spacing={2}
                columns={{ xs: 6, sm: 12 }}
                marginBlockEnd={1}
              >
                <Grid item xs={6}>
                  <TextField
                    label={t("Task Template Code")}
                    fullWidth
                    {...formProps.register("code", {
                      required: t("Task template code is required"),
                    })}
                    error={Boolean(formProps.formState.errors.code)}
                    helperText={Boolean(formProps.formState.errors.code) && t(formProps.formState.errors.code?.message!!)}
                  />
                </Grid>
                <Grid item xs={6}>
                  <TextField
                    label={t("Task Template Name")}
                    fullWidth
                    {...formProps.register("name", {
                      required: t("Task template name is required"),
                    })}
                    error={Boolean(formProps.formState.errors.name)}
                    helperText={Boolean(formProps.formState.errors.name) && t(formProps.formState.errors.name?.message!!)}
                  />
                </Grid>
              </Grid>
              <TransferList
                allItems={items}
                selectedItems={selectedItems}
                onChange={(selectedTasks) => {
                  // formProps.setValue(
                  //   "taskIds",
                  //   selectedTasks.map((item) => item.id),
                  // );

                  const newTaskGroups = selectedTasks.reduce<
                    NewTaskTemplateFormInputs["taskGroups"]
                  >((acc, item) => {
                    if (!item.group) {
                      // TODO: this should not happen (all tasks are part of a group)
                      return acc;
                    }
                    if (!acc[item.group.id]) {
                      return {
                        ...acc,
                        [item.group.id]: {
                          taskIds: [item.id],
                          percentAllocation:
                            currentTaskGroups[item.group.id]?.percentAllocation || 0,
                        },
                      };
                    }
                    return {
                      ...acc,
                      [item.group.id]: {
                        ...acc[item.group.id],
                        taskIds: [...acc[item.group.id].taskIds, item.id],
                      },
                    };
                  }, {});

                  formProps.setValue("taskGroups", newTaskGroups);
                }}
                allItemsLabel={t("Task Pool")}
                selectedItemsLabel={t("Task List Template")}
              />
            </CardContent>
          </Card>

          {/* Resource Allocation */}
          <Card>
            <CardContent>
              <ResourceAllocationWrapper
                allTasks={tasks}
                grades={grades}
              />
            </CardContent>
          </Card>
          {
            serverError && (
              <Typography variant="body2" color="error" alignSelf="flex-end">
                {serverError}
              </Typography>
            )
          }
          <Stack direction="row" justifyContent="flex-end" gap={1}>
            <Button variant="outlined" startIcon={<Close />} onClick={handleCancel}>
              {t("Cancel")}
            </Button>
            <Button
              variant="contained"
              startIcon={<Check />}
              type="submit"
              disabled={formProps.formState.isSubmitting}
            >
              {t("Confirm")}
            </Button>
          </Stack>
        </Stack >
      </FormProvider>
    </>
  );
};

export default CreateTaskTemplate;
