/* ---------------------------------- @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';
import { Download, Search as SearchIcon, Upload } from '@mui/icons-material';
/* ---------------------------------- types --------------------------------- */
import { DivisionDataProps, Order, PaginationTableProps, TableListProps } from '../@types/table';
import { InputAdornment } from '@mui/material';
import GetAppIcon from '@mui/icons-material/GetApp';
import { LanguageContext } from '@/contexts/LanguageContext';

/* --------------------------------- 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,
  filterStatus,
  filterStartDate,
  filterEndDate,
  searchs,
  exportReport,
}: 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);
  };
  
  const { localeData }: any =  useContext(LanguageContext);
  /* -------------------------------------------------------------------------- */

  /* -------------------------- 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],
      ['per_page', paginations.rowsPerPage]
    ]);
    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>
            ) : null }

            {searchs && searchs.useSearchs ? (
              <Fragment>
                {filterStatus && filterStatus.useFilter ? (
                  <Grid item xs={12} lg={10} xl={10}>
                    <form onSubmit={searchs.handleSearchSubmit}>
                      <TextField
                        id="search-input"
                        variant="outlined"
                        onChange={(event) => searchs.setSearchText(event.target.value)}
                        value={searchs.searchText}
                        fullWidth
                        InputProps={{
                          startAdornment: (
                            <InputAdornment position="start">
                              <SearchIcon />
                            </InputAdornment>
                          ),
                        }}
                        placeholder={localeData.txtSearch}
                      />
                    </form>
                </Grid>
                ) :
                  <Grid item xs={12} lg={6} xl={6}>
                    <form onSubmit={searchs.handleSearchSubmit}>
                      <TextField
                        id="search-input"
                        variant="outlined"
                        onChange={(event) => searchs.setSearchText(event.target.value)}
                        value={searchs.searchText}
                        fullWidth
                        InputProps={{
                          startAdornment: (
                            <InputAdornment position="start">
                              <SearchIcon />
                            </InputAdornment>
                          ),
                        }}
                        placeholder={localeData.txtSearch}
                      />
                    </form>
                  </Grid>
                }
                  
              </Fragment>
            ) : null }

            {/* Start date */}
            {filterStartDate && filterStartDate.useFilter ? (
              <Grid item xs={12} lg={2} xl={2}>
              <form onChange={(event) => filterStartDate.handleStartDateChange(event)}>
                <TextField
                  id="date-input"
                  type="date"
                  variant="outlined"
                  value={filterStartDate.startDate}
                  fullWidth
                  label="Start Date"
                  InputLabelProps={{
                    shrink: true,
                  }}
                />
              </form>
            </Grid>
            ) : null }

            {/* End Date */}

            {filterEndDate && filterEndDate.useFilter ? (
              <Grid item xs={12} lg={2} xl={2}>
              <form onChange={(event) => filterEndDate.handleEndDateChange(event)}>
                <TextField
                  id="date-input"
                  type="date"
                  variant="outlined"
                  value={filterEndDate.endDate}
                  fullWidth
                  label="End Date"
                  InputLabelProps={{
                    shrink: true,
                  }}
                />
              </form>
            </Grid>
            ) : null }

            {/* Filter status */}
            {filterStatus && filterStatus.useFilter ? (
               <Grid item xs={12} lg={2} xl={2}>
               <FormControl fullWidth>
                 <InputLabel id="simple-status-select-lable">Status</InputLabel>
                 <Select
                   labelId="simple-status-select-lable"
                   id="status-select-lable"
                   value={filterStatus.config.statusValue}
                   label="Status"
                   onChange={filterStatus.config.handleStatusChange}
                 >
                   <MenuItem value="all">{localeData.txtAll}</MenuItem>
                    {filterStatus.config.filterData.map((row: StatusDataProps, index) => (
                      <MenuItem key={index} value={row.id}>
                        {row.name}
                      </MenuItem>
                    ))}
                 </Select>
               </FormControl>
             </Grid>
            ) : null } 

            {/* Export Report */}

            {exportReport && exportReport.useExport ? (
               <Grid item xs={12} lg={2} xl={2}>
               <FormControl fullWidth>
                  <Button variant='contained' sx={{p:2}}>
                    <Download />
                    <Typography variant='inherit' sx={{marginLeft: 1}}>Export</Typography> 
                  </Button>
               </FormControl>
             </Grid>
            ) : null } 

          </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">
                      {localeData.txtDataNotFound}
                    </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>
  );
}
