'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 { useSnackbar } from '@/shared/components/snackbar';
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 { 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 TaskFavoriteTableRow from './task-favorite-table-row';
import TaskSearch from './task-search';
import TaskSort from './task-sort';
import TaskFilters from './task-filters';
import { orderBy } from 'lodash';
import TaskFiltersResult from './task-filters-result';
import TaskFilters1 from './task-filters';
import { archiveListTask, archiveTask, deleteListTask, deleteTask, favoriteTask, unfavoritListTask, unfavoriteTask, 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: 'managerId', label: 'Manager', align: 'center' },
  { id: 'column', label: 'Status' },
  { id: '' },
  { id: '' },
];


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

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

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

  const theme = useTheme();

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

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

  const confirm = useBoolean();

  const confirmArchive = useBoolean();

  const confirmFavorite = useBoolean();
  const selectedAgency = Number(localStorage.getItem('selectedAgency'));
  const { tasks, tasksLoading } = useGetTasks(selectedAgency, 'FAVORITE');


  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', 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: any) => task.name.toLowerCase().indexOf(search.query.toLowerCase()) !== -1
        );

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


  const handleResetFilters = useCallback(() => {
    setFilters(defaultFilters);
  }, []);
  //------------------Archive----------------------
  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('Project archived successfully', { variant: 'success' });

      } else {

        enqueueSnackbar('Failed to archive project', { 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('Projects archived successfully', { variant: 'success' });
    } catch (error) {
      enqueueSnackbar('archive projects Error', { variant: 'error' });

    }
  }, [dataFiltered.length, dataInPage.length, enqueueSnackbar, table, tableData]);
  //------------------------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]);
  //--------------------------------favorite-------------------------------------------

  const handleFavoriteRow = useCallback(async (id: number) => {

    try {

      const response = await favoriteTask(id);
      const updatedTableData = tableData.filter((row) => row.id !== id);
      setTableData(updatedTableData);
      if (response.code === 200) {
        confirm.onFalse();
        enqueueSnackbar('Task favorite successfully', { variant: 'success' });

      } else {

        enqueueSnackbar('Failed to favorite 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 handleUnFavoriteClick = useCallback(async (id: number) => {

    try {

      const response = await unfavoriteTask(id);
      const updatedTableData = tableData.filter((row) => row.id !== id);
      setTableData(updatedTableData);
      if (response.code === 200) {
        confirm.onFalse();
        enqueueSnackbar('Task unfavorite  successfully', { variant: 'success' });

      } else {

        enqueueSnackbar('Failed to unfavorite 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 handleUnFavoriteRows = useCallback(async () => {

    try {
      const response = await unfavoritListTask(table.selected.map(id => Number(id)));
      const unfavoritRows = tableData.filter((row) => !table.selected.includes(row.id.toString()));

      setTableData(unfavoritRows);

      table.onUpdatePageDeleteRows({
        totalRowsInPage: dataInPage.length,
        totalRowsFiltered: dataFiltered.length,
      });
      enqueueSnackbar('Tasks unfavorite 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,
        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}>
        <TaskFilters1
          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>
          <Stack
            spacing={2}
            justifyContent="space-between"
            direction={'row'}
          >
            <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>

          </Stack>
          <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="favorite-off">
                    <IconButton color="primary" onClick={confirmFavorite.onTrue}>
                      <Iconify icon="mdi:favorite-remove" />

                    </IconButton>
                  </Tooltip>
                  <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) => (
                      <TaskFavoriteTableRow
                        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)}
                        onUnFavoriteRow={() => handleUnFavoriteClick(row.id)}
                        onFavoriteRow={() => handleFavoriteRow(row.id)}
                        onUpdateTask={onUpdateTask}
                        onArchiveRow={() => handleArchiveRow(row.id)}
                      />
                    ))}


                  <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>
          }
        />

        <ConfirmDialog
          open={confirmFavorite.value}
          onClose={confirmFavorite.onFalse}
          title="Favorite-off"
          content={
            <>
              Are you sure you want to turn off favoriting  <strong> {table.selected.length} </strong> items?
            </>
          }
          action={
            <Button
              variant="contained"
              color="warning"
              onClick={() => {
                handleUnFavoriteRows();
                confirmFavorite.onFalse();
              }}
            >
              Turn off
            </Button>
          }
        />
      </LocalizationProvider>
    </>

  );
}

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

function applyFilter({
  inputData,
  comparator,
  filters,
  sortBy,
  dateError,
}: {
  inputData: ITaskItem[];
  comparator: (a: any, b: any) => number;
  filters: ITaskTableFilters;
  sortBy: string;
  dateError: boolean;
}) {
  const { name, type, manager, column, startDate, endDate } = filters;
  let filteredData = [...inputData];

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

  const managerIds = manager.map((manager) => manager.id);
  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 (type.length) {
    filteredData = filteredData.filter((task) => type.includes(task.type));
  }
  if (managerIds.length) {
    filteredData = filteredData.filter((task) => task.managerId &&
      managerIds.includes(task.managerId)//managerIds.includes(task.manager.id)

    );
  }

  // SORT BY
  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;
}
