"use client";

import sumBy from "lodash/sumBy";
import { useState, useCallback, useEffect } from "react";

import Tab from "@mui/material/Tab";
import Tabs from "@mui/material/Tabs";
import Card from "@mui/material/Card";
import Table from "@mui/material/Table";
import Stack from "@mui/material/Stack";
import Button from "@mui/material/Button";
import Divider from "@mui/material/Divider";
import Tooltip from "@mui/material/Tooltip";
import Container from "@mui/material/Container";
import TableBody from "@mui/material/TableBody";
import IconButton from "@mui/material/IconButton";
import { alpha, useTheme } from "@mui/material/styles";
import TableContainer from "@mui/material/TableContainer";
import LocalizationProvider from "@/shared/locales/localization-provider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { paths } from "@/routes/paths";
import { useRouter } from "@/hooks";
import RouterLink from "@/routes/router-link";

import { useBoolean } from "@/hooks";

import { isAfter, isBetween } from "@/utils/format-time";

import {
  TASK_SORT_OPTIONS,
  TASK_TYPE_OPTIONS,
  _managers,
  _tasks,
} from "@/shared/_mock";

import Label from "@/shared/components/label";
import Iconify from "@/shared/components/iconify";
import Scrollbar from "@/shared/components/scrollbar";
import { useSnackbar } from "@/components/snackbar";
import { ConfirmDialog } from "@/shared/components/custom-dialog";
import { useSettingsContext } from "@/shared/components/settings";
import CustomBreadcrumbs from "@/components/custom-breadcrumbs";
import {
  useTable,
  emptyRows,
  TableNoData,
  getComparator,
  TableHeadCustom,
  TableSelectedAction,
  TablePaginationCustom,
  TableEmptyRows,
} from "@/shared/components/table";

import {
  ITaskItem,
  ITaskTableFilterValue,
  ITaskTableFilters,
} from "@/contexts/types/tasks";
import TaskTableRow from "../all-tasks/task-table-row";
import TaskSearch from "../all-tasks/task-search";
import TaskSort from "../all-tasks/task-sort";
import TaskFilters from "../all-tasks/task-filters";
import TaskFiltersResult from "../all-tasks/task-filters-result";
import { orderBy } from "lodash";
import { useGetTasksOfProject } from "@/shared/api/project";
import {
  archiveListTask,
  archiveTask,
  deleteListTask,
  deleteTask,
} from "@/shared/api/task";

// ----------------------------------------------------------------------

const TABLE_HEAD = [
  { id: "name", label: "Name" },
  { id: "startDate", label: "Create" },
  { id: "endDate", label: "Due" },
  { id: "priority", label: "Priority" },
  { id: "type", label: "Type" },
  { id: "manager", label: "Manager", align: "center" },
  { id: "status", label: "Status" },  { id: "" },
  { id: "" },

];

const defaultFilters: ITaskTableFilters = {
  name: "",
  manager: [],
  column: {
    id: 0,
    name: "all",
    tasks: [],
    orderIndex: 0,
  },
  type: [],
  startDate: null,
  endDate: null,
};

// ----------------------------------------------------------------------
type Props = {
  projectId: number;
};
export default function AllTasksView({ projectId }: Props) {
  const { enqueueSnackbar } = useSnackbar();
  const { tasks, tasksLoading } = useGetTasksOfProject(projectId);

  const theme = useTheme();

  const settings = useSettingsContext();
  const openFilters = useBoolean();
  const router = useRouter();

  const table = useTable({ defaultOrderBy: "startDate" });

  const confirm = useBoolean();

  const [tableData, setTableData] = useState<ITaskItem[]>(tasks);
  const confirmArchive = useBoolean();

  const [filters, setFilters] = useState(defaultFilters);

  const dateError = isAfter(filters.startDate, filters.endDate);

  const [sortBy, setSortBy] = useState("latest");

  const [search, setSearch] = useState<{ query: string; results: ITaskItem[] }>(
    {
      query: "",
      results: [],
    }
  );
  useEffect(() => {
    if (tasks.length) {
      setTableData(tasks);
    }
  }, [tasks]);

  const [selectedTaskId, setSelectedTaskId] = useState<number | null>(null);

  const handleViewRow = useCallback(
    (id: number) => {
      setSelectedTaskId(id);
    },
    [table]
  );

  const dataFiltered = applyFilter({
    inputData: tableData,
    comparator: getComparator(table.order, table.orderBy),
    filters,
    sortBy,
    dateError,
  });

  const dataInPage = dataFiltered.slice(
    table.page * table.rowsPerPage,
    table.page * table.rowsPerPage + table.rowsPerPage
  );

  const denseHeight = table.dense ? 56 : 56 + 20;

  const canReset =
    !!filters.name ||
    filters.column.name !== "all" ||
    !!filters.type.length ||
    !!filters.manager.length ||
    (!!filters.startDate && !!filters.endDate);

  const notFound = (!dataFiltered.length && canReset) || !dataFiltered.length;

  const getTaskLength = (status: string) =>
    tableData.filter((item) => item.status === status).length;

  const TABS = [
    { value: "all", label: "All", color: "default", count: tableData.length },
    {
      value: "TO DO",
      label: "To Do",
      color: "error",
      count: getTaskLength("TO DO"),
    },
    {
      value: "IN PROGRESS",
      label: "In Progress",
      color: "warning",
      count: getTaskLength("IN PROGRESS"),
    },
    {
      value: "DONE",
      label: "Done",
      color: "success",
      count: getTaskLength("DONE"),
    },
  ] as const;

  const handleFilters = useCallback(
    (name: string, value: ITaskTableFilterValue) => {
      table.onResetPage();
      setFilters((prevState) => ({
        ...prevState,
        [name]: value,
      }));
    },
    [table]
  );

  //----------------------------------------------------------------------------------
  const handleSortBy = useCallback((newValue: string) => {
    setSortBy(newValue);
  }, []);

  const handleSearch = useCallback(
    (inputValue: string) => {
      setSearch((prevState) => ({
        ...prevState,
        query: inputValue,
      }));

      if (inputValue) {
        const results = _tasks.filter(
          (task) =>
            task.name.toLowerCase().indexOf(search.query.toLowerCase()) !== -1
        );

        setSearch((prevState) => ({
          ...prevState,
          results,
        }));
      }
    },
    [search.query]
  );
  //----------------------------------------------------------------------------------

  const handleResetFilters = useCallback(() => {
    setFilters(defaultFilters);
  }, []);
  //-----------------------Archive & Delete-------------------
  const handleDeleteRow = useCallback(
    async (id: number) => {
      try {
        const response = await deleteTask(id);

        if (response.code === 200) {
          const updatedTableData = tableData.filter((row) => row.id !== id);
          setTableData(updatedTableData);

          confirm.onFalse();
          enqueueSnackbar("task deleted successfully", { variant: "success" });
        } else {
          enqueueSnackbar("Failed to delete task", { variant: "error" });
        }
      } catch (error) {
        console.error("An error occurred:", error);
        enqueueSnackbar("An error occurred. Please try again later.", {
          variant: "error",
        });
      }
    },
    [tableData, table, enqueueSnackbar]
  );

  const handleDeleteRows = useCallback(async () => {
    try {
      const response = await deleteListTask(
        table.selected.map((id) => Number(id))
      );
      const deleteRows = tableData.filter(
        (row) => !table.selected.includes(row.id.toString())
      );

      setTableData(deleteRows);

      table.onUpdatePageDeleteRows({
        totalRowsInPage: dataInPage.length,
        totalRowsFiltered: dataFiltered.length,
      });
      enqueueSnackbar("tasks deleted successfully", { variant: "success" });
    } catch (error) {
      enqueueSnackbar("delete tasks Error", { variant: "error" });
    }
  }, [
    dataFiltered.length,
    dataInPage.length,
    enqueueSnackbar,
    table,
    tableData,
  ]);

  const handleArchiveRow = useCallback(
    async (id: number) => {
      try {
        const response = await archiveTask(id);
        const updatedTableData = tableData.filter((row) => row.id !== id);
        setTableData(updatedTableData);

        if (response.code === 200) {
          enqueueSnackbar("Task archived successfully", { variant: "success" });
        } else {
          enqueueSnackbar("Failed to archive task", { variant: "error" });
        }
      } catch (error) {
        console.error("An error occurred:", error);
        enqueueSnackbar("An error occurred. Please try again later.", {
          variant: "error",
        });
      }
    },
    [tableData, table, enqueueSnackbar]
  );

  const handleArchiveRows = useCallback(async () => {
    try {
      const response = await archiveListTask(
        table.selected.map((id) => Number(id))
      );
      const archiveRows = tableData.filter(
        (row) => !table.selected.includes(row.id.toString())
      );

      setTableData(archiveRows);

      table.onUpdatePageDeleteRows({
        totalRowsInPage: dataInPage.length,
        totalRowsFiltered: dataFiltered.length,
      });
      enqueueSnackbar("Tasks archived successfully", { variant: "success" });
    } catch (error) {
      enqueueSnackbar("archive tasks Error", { variant: "error" });
    }
  }, [
    dataFiltered.length,
    dataInPage.length,
    enqueueSnackbar,
    table,
    tableData,
  ]);

  //----------------------------------------------------------

  const handleFilterStatus = useCallback(
    (event: React.SyntheticEvent, newValue: string) => {
      handleFilters("column", {
        id: 0,
        name: newValue,
        tasks: [],
        orderIndex: 0,
      });
    },
    [handleFilters]
  );

  //----------------view details--------------

  const [selectedTask, setSelectedTask] = useState<ITaskItem | null>(null);
  const handelSelectedTask = (task: any) => {
    setSelectedTask(task);
  };
  function onUpdateTask(updateTask: ITaskItem): void {
    throw new Error("Function not implemented.");
  }

  return (
    <>
      <LocalizationProvider>
        <Container maxWidth={settings.themeStretch ? false : "lg"}>
          <Card sx={{ ml: { xs: -1, md: -3 }, p: 2 }}>
            <Tabs
              value={filters.column.name}
              onChange={handleFilterStatus}
              sx={{
                px: 2.5,
                boxShadow: `inset 0 -2px 0 0 ${alpha(
                  theme.palette.grey[500],
                  0.08
                )}`,
              }}
            >
              {TABS.map((tab) => (
                <Tab
                  key={tab.value}
                  value={tab.value}
                  label={tab.label}
                  iconPosition="end"
                  icon={
                    <Label
                      variant={
                        ((tab.value === "all" ||
                          tab.value === filters.column.name) &&
                          "filled") ||
                        "soft"
                      }
                      color={tab.color}
                    >
                      {tab.count}
                    </Label>
                  }
                />
              ))}
            </Tabs>

            <TableContainer sx={{ position: "relative", overflow: "unset" }}>
              <TableSelectedAction
                dense={table.dense}
                numSelected={table.selected.length}
                rowCount={dataFiltered.length}
                onSelectAllRows={(checked) => {
                  table.onSelectAllRows(
                    checked,
                    dataFiltered.map((row) => row.id.toString())
                  );
                }}
                action={
                  <Stack direction="row">
                    <Tooltip title="Archive">
                      <IconButton
                        color="primary"
                        onClick={confirmArchive.onTrue}
                      >
                        <Iconify icon="clarity:archive-solid" />
                      </IconButton>
                    </Tooltip>

                    <Tooltip title="Delete">
                      <IconButton color="primary" onClick={confirm.onTrue}>
                        <Iconify icon="solar:trash-bin-trash-bold" />
                      </IconButton>
                    </Tooltip>
                  </Stack>
                }
              />

              <Scrollbar>
                <Table
                  size={table.dense ? "small" : "medium"}
                  sx={{ minWidth: 800 }}
                >
                  <TableHeadCustom
                    order={table.order}
                    orderBy={table.orderBy}
                    headLabel={TABLE_HEAD}
                    rowCount={dataFiltered.length}
                    numSelected={table.selected.length}
                    onSort={table.onSort}
                    onSelectAllRows={(checked) =>
                      table.onSelectAllRows(
                        checked,
                        dataFiltered.map((row) => row.id.toString())
                      )
                    }
                  />

                  <TableBody>
                    {dataFiltered
                      .slice(
                        table.page * table.rowsPerPage,
                        table.page * table.rowsPerPage + table.rowsPerPage
                      )
                      .map((row) => (
                        <TaskTableRow
                          key={row.id}
                          row={row}
                          selected={table.selected.includes(row.id.toString())}
                          onSelectRow={() =>
                            table.onSelectRow(row.id.toString())
                          }
                          onDeleteRow={() => handleDeleteRow(row.id)}
                          onArchiveRow={() => handleArchiveRow(row.id)}
                          onUpdateTask={onUpdateTask}
                        />
                      ))}

                    <TableEmptyRows
                      height={denseHeight}
                      emptyRows={emptyRows(
                        table.page,
                        table.rowsPerPage,
                        dataFiltered.length
                      )}
                    />

                    <TableNoData notFound={notFound} />
                  </TableBody>
                </Table>
              </Scrollbar>
            </TableContainer>

            <TablePaginationCustom
              count={dataFiltered.length}
              page={table.page}
              rowsPerPage={table.rowsPerPage}
              onPageChange={table.onChangePage}
              onRowsPerPageChange={table.onChangeRowsPerPage}
              dense={table.dense}
              onChangeDense={table.onChangeDense}
            />
          </Card>
        </Container>

        <ConfirmDialog
          open={confirm.value}
          onClose={confirm.onFalse}
          title="Delete"
          content={
            <>
              Are you sure want to delete{" "}
              <strong> {table.selected.length} </strong> items?
            </>
          }
          action={
            <Button
              variant="contained"
              color="error"
              onClick={() => {
                handleDeleteRows();
                confirm.onFalse();
              }}
            >
              Delete
            </Button>
          }
        />
        <ConfirmDialog
          open={confirmArchive.value}
          onClose={confirmArchive.onFalse}
          title="Archive"
          content={
            <>
              Are you sure want to archive
              <strong> {table.selected.length} </strong> items?
            </>
          }
          action={
            <Button
              variant="contained"
              color="error"
              onClick={() => {
                handleArchiveRows();
                confirmArchive.onFalse();
              }}
            >
              Archive
            </Button>
          }
        />
      </LocalizationProvider>
    </>
  );
}

// ----------------------------------------------------------------------

function applyFilter({
  inputData,
  comparator,
  filters,
  sortBy,
  dateError,
}: {
  inputData: ITaskItem[];
  comparator: (a: any, b: any) => number;
  filters: ITaskTableFilters;
  // filTask;
  sortBy: string;
  dateError: boolean;
}) {
  const { name, type, manager, column, startDate, endDate } = filters; //
  const managerIds = manager.map((manager) => manager.id);
  const stabilizedThis = inputData.map((el, index) => [el, index] as const);

  stabilizedThis.sort((a, b) => {
    const order = comparator(a[0], b[0]);
    if (order !== 0) return order;
    return a[1] - b[1];
  });

  inputData = stabilizedThis.map((el) => el[0]);

  if (name) {
    inputData = inputData.filter(
      (task) => task.name.toLowerCase().indexOf(name.toLowerCase()) !== -1
    );
  }

  if (column.name !== "all") {
    inputData = inputData.filter((task) => task.status === column.name);
  }

  if (!dateError) {
    if (startDate && endDate) {
      inputData = inputData.filter((task) =>
        isBetween(task.startDate, startDate, endDate)
      );
    }
  }
  if (type.length) {
    inputData = inputData.filter((task) => type.includes(task.type));
  }
  if (managerIds.length) {
    inputData = inputData.filter(
      (task) => task.managerId && managerIds.includes(task.managerId)
    );
  }

  // SORT BY
  if (sortBy === "latest") {
    inputData = orderBy(inputData, ["createdAt"], ["desc"]);
  }

  if (sortBy === "oldest") {
    inputData = orderBy(inputData, ["createdAt"], ["asc"]);
  }

  if (sortBy === "popular") {
    inputData = orderBy(inputData, ["totalViews"], ["desc"]);
  }

  return inputData;
}
