"use client";

import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
import { useTranslation } from "react-i18next";
import TransferList from "../TransferList";
import Button from "@mui/material/Button";
import React, { useCallback, useMemo, useState } from "react";
import CardActions from "@mui/material/CardActions";
import RestartAlt from "@mui/icons-material/RestartAlt";
import FormControl from "@mui/material/FormControl";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import MenuItem from "@mui/material/MenuItem";
import InputLabel from "@mui/material/InputLabel";
import { Task, TaskTemplate } from "@/app/api/tasks";
import { useFormContext } from "react-hook-form";
import { CreateProjectInputs } from "@/app/api/projects/actions";
import isNumber from "lodash/isNumber";
import intersectionWith from "lodash/intersectionWith";

interface Props {
  allTasks: Task[];
  taskTemplates: TaskTemplate[];
  isActive: boolean;
}

const TaskSetup: React.FC<Props> = ({
  allTasks: tasks,
  taskTemplates,
  isActive,
}) => {
  const { t } = useTranslation();
  const { setValue, watch } = useFormContext<CreateProjectInputs>();
  const currentTaskGroups = watch("taskGroups");
  const currentTaskIds = Object.values(currentTaskGroups).reduce<Task["id"][]>(
    (acc, group) => {
      return [...acc, ...group.taskIds];
    },
    [],
  );

  const onReset = useCallback(() => {
    setValue("taskGroups", {});
  }, [setValue]);

  const [selectedTaskTemplateId, setSelectedTaskTemplateId] = useState<
    "All" | number
  >("All");
  const onSelectTaskTemplate = useCallback(
    (e: SelectChangeEvent<number | "All">) => {
      if (e.target.value === "All" || isNumber(e.target.value)) {
        setSelectedTaskTemplateId(e.target.value);
        // onReset();
      }
    },
    [onReset],
  );

  const items = useMemo(() => {
    const taskList =
      selectedTaskTemplateId === "All"
        ? tasks
        : taskTemplates.find(
            (template) => template.id === selectedTaskTemplateId,
          )?.tasks || tasks;

    return taskList.map((t) => ({
      id: t.id,
      label: t.name,
      group: t.taskGroup,
    }));
  }, [tasks, selectedTaskTemplateId, taskTemplates]);

  const selectedItems = useMemo(() => {
    return intersectionWith(
      tasks,
      currentTaskIds,
      (task, taskId) => task.id === taskId,
    ).map((t) => ({ id: t.id, label: t.name, group: t.taskGroup }));
  }, [currentTaskIds, tasks]);

  return (
    <Card sx={{ display: isActive ? "block" : "none" }}>
      <CardContent sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
        <Typography variant="overline" display="block" marginBlockEnd={1}>
          {t("Task List Setup")}
        </Typography>
        <Grid
          container
          spacing={2}
          columns={{ xs: 6, sm: 12 }}
          marginBlockEnd={1}
        >
          <Grid item xs={6}>
            <FormControl fullWidth>
              <InputLabel>{t("Task List Source")}</InputLabel>
              <Select<"All" | number>
                label={t("Task List Source")}
                value={selectedTaskTemplateId}
                onChange={onSelectTaskTemplate}
              >
                <MenuItem value={"All"}>{t("All tasks")}</MenuItem>
                {taskTemplates.map((template, index) => (
                  <MenuItem key={`${template.id}-${index}`} value={template.id}>
                    {template.name}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>
        </Grid>
        <TransferList
          allItems={items}
          selectedItems={selectedItems}
          onChange={(selectedTasks) => {
            const newTaskGroups = selectedTasks.reduce<
              CreateProjectInputs["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],
                },
              };
            }, {});

            setValue("taskGroups", newTaskGroups);
          }}
          allItemsLabel={t("Task Pool")}
          selectedItemsLabel={t("Project Task List")}
        />
        <CardActions sx={{ justifyContent: "flex-end" }}>
          <Button variant="text" startIcon={<RestartAlt />} onClick={onReset}>
            {t("Reset")}
          </Button>
        </CardActions>
      </CardContent>
    </Card>
  );
};

export default TaskSetup;
