"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 TaskArchivedTableRow from "./task-archived-table-row";
import TaskSearch from "./task-search";
import TaskSort from "./task-sort";
import TaskFilters from "./task-filters";
import TaskFiltersResult from "./task-filters-result";
import { orderBy } from "lodash";
import {
  deleteListTask,
  deleteTask,
  recoverListTask,
  recoverTask,
  useGetTasks,
} from "@/shared/api/task";

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

const TABLE_HEAD = [
  { id: "name", label: "Name" },
  { id: "startDate", label: "Create" },
  { id: "endDate", label: "Due" },
  { id: "type", label: "Type" },
  { id: "manager", label: "Manager", align: "center" },
  { id: "column", label: "Status" },
  { id: null },
];

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

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

export default function TaskArchivedList() {
  const { enqueueSnackbar } = useSnackbar();

  const theme = useTheme();

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

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

  const confirm = useBoolean();
  const confirmRecover = useBoolean();
  const selectedAgency = Number(localStorage.getItem('selectedAgency'));
  const { tasks, tasksLoading } = useGetTasks(selectedAgency, "ARCHIVED");

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

  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: [],
    }
  );
  //----------------integration----------------
  useEffect(() => {
    if (tasks.length) {
      setTableData(tasks);
    }
  }, [tasks]);
  //-------------------------------------------
  const onUpdateTask = (updatedTask: ITaskItem) => {
    setTableData((prevTasks) =>
      prevTasks.map((task) => (task.id === updatedTask.id ? updatedTask : task))
    );
  };
  //-------------------------------------------
  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" as const, count: tableData.length },
    {
      value: "TO DO",
      label: "To Do",
      color: "error" as const,
      count: getTaskLength("TO DO"),
    },
    {
      value: "IN PROGRESS",
      label: "In Progress",
      color: "warning" as const,
      count: getTaskLength("IN PROGRESS"),
    },
    {
      value: "DONE",
      label: "Done",
      color: "success" as const,
      count: getTaskLength("DONE"),
    },
  ];

  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: { name: string }) =>
            task.name.toLowerCase().indexOf(search.query.toLowerCase()) !== -1
        );

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

  const handleResetFilters = useCallback(() => {
    setFilters(defaultFilters);
  }, []);

  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 handleRecoverRow = useCallback(
    async (id: number) => {
      try {
        const response = await recoverTask(id);
        const updatedTableData = tableData.filter((row) => row.id !== id);
        setTableData(updatedTableData);

        if (response.code == 200) {
          enqueueSnackbar("Task recovred successfully", { variant: "success" });
        } else {
          enqueueSnackbar("Failed to recover task", { variant: "error" });
        }
      } catch (error) {
        enqueueSnackbar("Recover task Error", { variant: "error" });

        console.error("Recover task Error  :", error);
      }
    },
    [tableData, table, enqueueSnackbar]
  );

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

      setTableData(recoverRows);

      table.onUpdatePageDeleteRows({
        totalRowsInPage: dataInPage.length,
        totalRowsFiltered: dataFiltered.length,
      });
      enqueueSnackbar("tasks recovred successfully", { variant: "success" });
    } catch (error) {
      enqueueSnackbar("recover 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,
        orderIndex: 0,
        tasks: []
      });
    },
    [handleFilters]
  );

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

  const [selectedTask, setSelectedTask] = useState<ITaskItem | null>(null);
  const handelSelectedTask = (task: any) => {
    setSelectedTask(task);
  };
  const handleViewRow = useCallback(
    (id: number) => {
      const task = tableData.find((t) => t.id === id);
      handelSelectedTask(task);
    },
    [tableData]
  );

  const renderFilters = (
    <Stack
      spacing={3}
      justifyContent="space-between"
      alignItems={{ xs: "flex-end", sm: "center" }}
      direction={{ xs: "column", sm: "row" }}
    >
      <TaskSearch
        query={search.query}
        results={search.results}
        onSearch={handleSearch}
        hrefItem={(id: string) => paths.dashboard.tasks.details(id)}
      />

      <Stack direction="row" spacing={1} flexShrink={0}>
        <TaskFilters
          open={openFilters.value}
          onOpen={openFilters.onTrue}
          onClose={openFilters.onFalse}
          filters={filters}
          onFilters={handleFilters}
          canReset={canReset}
          onResetFilters={handleResetFilters}
          managerOptions={_managers}
          typeOptions={TASK_TYPE_OPTIONS.map((option) => option.label)}
          dateError={dateError}
        />

        <TaskSort
          sort={sortBy}
          onSort={handleSortBy}
          sortOptions={TASK_SORT_OPTIONS}
        />
      </Stack>
      <Button
        component={RouterLink}
        href={paths.dashboard.tasks.add_task}
        variant="contained"
        startIcon={<Iconify icon="mingcute:add-line" />}
        sx={{
          backgroundColor: '#144dd5',
          '&:hover': {
            backgroundColor: '#144dd5',
          },
          width: '19.2%',
          height: '100%',
          textTransform: 'none',
        }}
      >
        New Task
      </Button>
    </Stack>
  );

  const renderResults = (
    <TaskFiltersResult
      filters={filters}
      onResetFilters={handleResetFilters}
      canReset={canReset}
      onFilters={handleFilters}
      results={dataFiltered.length}
    />
  );

  return (
    <>
      <LocalizationProvider>
        <Stack
          spacing={2.5}
          sx={{
            mb: { xs: 3, md: 5 },
          }}
        >
          {renderFilters}

          {canReset && renderResults}
        </Stack>

        <Card>
          <Tabs
            value={filters.column.name}
            onChange={handleFilterStatus}
            sx={{
              px: 2.5,
              boxShadow: (theme) => `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="Recover">
                    <IconButton color="primary" onClick={confirmRecover.onTrue}>
                      <Iconify icon="lets-icons:back" />
                    </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) => (
                      <TaskArchivedTableRow
                        key={row.id}
                        row={row}
                        selected={table.selected.includes(row.id.toString())}
                        onSelectRow={() => table.onSelectRow(row.id.toString())}
                        onViewRow={() => handleViewRow(row.id)}
                        selectedTask={selectedTask}
                        onDeleteRow={() => handleDeleteRow(row.id)}
                        onRecoverRow={() => handleRecoverRow(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={confirmRecover.value}
          onClose={confirmRecover.onFalse}
          title="Recover"
          content={
            <>
              Are you sure want to recover{" "}
              <strong> {table.selected.length} </strong> items?
            </>
          }
          action={
            <Button
              variant="contained"
              color="success"
              onClick={() => {
                handleRecoverRows();
                confirmRecover.onFalse();
              }}
            >
              Recover
            </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;
  let filteredData = [...inputData];

  // Filter by status
  if (column?.name && column.name !== "all") {
    filteredData = filteredData.filter(
      (task) => task.status === column.name
    );
  }

  // Sort the data based on the provided comparator
  const stabilizedThis = filteredData.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];
  });
  filteredData = stabilizedThis.map((el) => el[0]);

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

  if (!dateError) {
    if (startDate && endDate) {
      filteredData = filteredData.filter((task) =>
        isBetween(task.startDate, startDate, endDate)
      );
    }
  }
  if (type.length) {
    filteredData = filteredData.filter((task) => type.includes(task.type));
  }
  if (manager.length) {
    const managerIds = manager.map((manager) => manager.id);
    filteredData = filteredData.filter(
      (task) => task.managerId && managerIds.includes(task.managerId) //manager.id
    );
  }

  // Update sorting logic to match task-list-view
  if (sortBy === 'latest') {
    filteredData = orderBy(filteredData, ['startDate'], ['desc']);
  } else if (sortBy === 'oldest') {
    filteredData = orderBy(filteredData, ['startDate'], ['asc']);
  } else if (sortBy === 'popular') {
    filteredData = orderBy(filteredData, ['priority'], ['desc']);
  }

  return filteredData;
}
