/* ---------------------------------- @mui ---------------------------------- */
import { styled } from '@mui/material/styles';
import {
  Paper,
  Table as TableContent,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Button,
  TableSortLabel,
  Box,
  Card,
  Grid,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  SelectChangeEvent,
  Stack,
  Typography,
  LinearProgress,
  linearProgressClasses,
} from '@mui/material';
import { visuallyHidden } from '@mui/utils';
/* ---------------------------------- axios --------------------------------- */
import axios from '../utils/axios';
/* ---------------------------------- react --------------------------------- */
import { Fragment, useContext, useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
/* -------------------------------- component ------------------------------- */
import BaseTablePagination from './BaseTablePagination';
/* ---------------------------------- theme --------------------------------- */
import palette from '../theme/palette';
/* ---------------------------------- utils --------------------------------- */
import { UserCurrentCorporateContext } from '../contexts/UserCurrentCorporate';
import { fSplit } from '../utils/formatNumber';
/* ---------------------------------- types --------------------------------- */
import { DivisionDataProps, Order, PaginationTableProps, TableListProps } from '../@types/table';

/* --------------------------------- styled --------------------------------- */
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
  height: 10,
  borderRadius: 6,
  [`&.${linearProgressClasses.colorPrimary}`]: {
    backgroundColor: '#D1F1F1',
  },
  [`& .${linearProgressClasses.bar}`]: {
    borderRadius: 6,
    backgroundColor: theme.palette.primary.main,
  },
}));
/* -------------------------------------------------------------------------- */

export default function Table<T>({
  headCells,
  rows,
  paginations,
  orders,
  loadings,
  params,
  filters,
  searchs,
}: TableListProps<T>) {
  /* ------------------------------- handle sort ------------------------------ */
  const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => {
    const isAsc = orders?.orderBy === property && orders?.order === 'asc';

    orders?.setOrder(isAsc ? 'desc' : 'asc');
    orders?.setOrderBy(property);
    const parameters = Object.fromEntries([
      ...params.searchParams.entries(),
      ['order', isAsc ? 'desc' : 'asc'],
      ['orderBy', property],
    ]);
    params.setAppliedParams(parameters);
  };
  /* -------------------------------------------------------------------------- */

  /* -------------------------- enchanced table head -------------------------- */
  const EnhancedTableHead = () => {
    const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => {
      handleRequestSort(event, property);
    };

    return (
      <TableHead>
        <TableRow>
          {headCells &&
            headCells.map((headCell, index) => (
              <TableCell
                key={index}
                sortDirection={orders?.orderBy === headCell.id ? orders.order : false}
                // @ts-ignore
                align={headCell.align}
                sx={{ padding: 2 }}
                width={headCell.width ? headCell.width : 'auto'}
              >
                {headCell.isSort ? (
                  <TableSortLabel
                    active={orders?.orderBy === headCell.id}
                    direction={orders?.orderBy === headCell.id ? orders.order : 'asc'}
                    onClick={createSortHandler(headCell.id)}
                  >
                    {headCell.label}
                    {orders?.orderBy === headCell.id ? (
                      <Box component="span" sx={visuallyHidden}>
                        {orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'}
                      </Box>
                    ) : null}
                  </TableSortLabel>
                ) : (
                  headCell.label
                )}
              </TableCell>
            ))}
        </TableRow>
      </TableHead>
    );
  };
  /* -------------------------------------------------------------------------- */

  /* ------------------------ button change pagination ------------------------ */
  const onPageChangeHandle = async (
    event: React.MouseEvent<HTMLButtonElement> | null,
    newPage: number
  ) => {
    const parameters = Object.fromEntries([
      ...params.searchParams.entries(),
      ['page', newPage + 1],
    ]);
    paginations.setPage(newPage);
    await new Promise((resolve) => setTimeout(resolve, 500));
    params.setAppliedParams(parameters);
  };
  /* -------------------------------------------------------------------------- */

  /* --------------------------- row page per limit --------------------------- */
  const onRowsPerPageChangeHandle = async (event: React.ChangeEvent<HTMLInputElement>) => {
    params.searchParams.delete('page');
    const parameters = Object.fromEntries([
      ...params.searchParams.entries(),
      ['per_page', parseInt(event.target.value, 10)],
    ]);

    paginations.setPage(0);
    paginations.setRowsPerPage(parseInt(event.target.value, 10));
    await new Promise((resolve) => setTimeout(resolve, 500));
    params.setAppliedParams(parameters);
  };
  /* -------------------------------------------------------------------------- */

  return (
    <Card>
      <Grid container>
        {/* Field 1 */}
        <Grid item xs={12} paddingX="24px" paddingY="20px">
          <Grid container spacing={2}>
            {filters && filters.useFilter ? (
              <Fragment>
                <Grid item xs={12} lg={3} xl={2}>
                  <FormControl fullWidth>
                    <InputLabel id="simple-division-select-lable">Division</InputLabel>
                    <Select
                      labelId="simple-division-select-lable"
                      id="division-select-lable"
                      value={filters.config.divisionValue}
                      label="Division"
                      onChange={filters.config.handleDivisionChange}
                    >
                      <MenuItem value="all">All</MenuItem>
                      {filters.config.divisionData.map((row: DivisionDataProps, index) => (
                        <MenuItem key={index} value={row.id}>
                          {row.name}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>
                </Grid>
                <Grid item xs={12} lg={9} xl={10}>
                  <form onSubmit={searchs.handleSearchSubmit}>
                    <TextField
                      id="search-input"
                      label="Search"
                      variant="outlined"
                      onChange={(event) => searchs.setSearchText(event.target.value)}
                      value={searchs.searchText}
                      fullWidth
                    />
                  </form>
                </Grid>
              </Fragment>
            ) : (
              <Grid item xs={12}>
                <form onSubmit={searchs.handleSearchSubmit}>
                  <TextField
                    id="search-input"
                    label="Search"
                    variant="outlined"
                    onChange={(event) => searchs.setSearchText(event.target.value)}
                    value={searchs.searchText}
                    fullWidth
                  />
                </form>
              </Grid>
            )}
          </Grid>
        </Grid>
        {/* End Field 1 */}
        {/* Field 2 */}
        <Grid item xs={12}>
          {/* Table */}
          <TableContainer component={Paper}>
            <TableContent aria-label="collapsible table" size="small">
              {/* Table Header */}
              <EnhancedTableHead />
              {/* End Table Header */}
              {/* Table Body */}
              <TableBody>
                {loadings.isLoading ? (
                  <TableRow>
                    <TableCell colSpan={headCells?.length} align="center">
                      Loading . . .
                    </TableCell>
                  </TableRow>
                ) : rows && rows.length >= 1 ? (
                  rows.map((row, rowIndex) => (
                    <TableRow key={rowIndex}>
                      {headCells &&
                        //@ts-ignore
                        headCells.map((head, headIndex) => (
                          //@ts-ignore
                          <TableCell align={head.align} key={headIndex}>
                            {row[head.id]}
                          </TableCell>
                        ))}
                    </TableRow>
                  ))
                ) : (
                  <TableRow>
                    <TableCell colSpan={6} align="center">
                      No Data Found
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
              {/* End Table Body */}
            </TableContent>
          </TableContainer>
          {/* End Table */}

          {/* Pagination */}
          <BaseTablePagination
            count={paginations.paginationTable.total}
            onPageChange={onPageChangeHandle}
            page={paginations.page}
            rowsPerPage={paginations.rowsPerPage}
            onRowsPerPageChange={onRowsPerPageChangeHandle}
          />
          {/* End Pagination */}
        </Grid>
        {/* End Field 2 */}
      </Grid>
    </Card>
  );
}
