/* ---------------------------------- @mui ---------------------------------- */
import { styled } from '@mui/material/styles';
import {
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Button,
  TableSortLabel,
  Box,
  IconButton,
  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 { useContext, useEffect, useState } from 'react';
/* -------------------------------- component ------------------------------- */
import Iconify from '../../components/Iconify';
import BaseTablePagination from '../../components/BaseTablePagination';
/* ---------------------------------- theme --------------------------------- */
import palette from '../../theme/palette';
import { useSearchParams } from 'react-router-dom';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import { fSplit } from '../../utils/formatNumber';

/* ---------------------------------- types --------------------------------- */
type PaginationTableProps = {
  current_page: number;
  from: number;
  last_page: number;
  links: [];
  path: string;
  per_page: number;
  to: number;
  total: number;
};

type DataTableProps = {
  fullName: string;
  memberId: string;
  division: string;
  limit: {
    current: number;
    total: number;
    percentage: number;
  };
  status: number;
};

type Order = 'asc' | 'desc';

interface HeadCell {
  id: string;
  align: string;
  label: string;
  isSort: boolean;
}

interface EnhancedTableProps {
  onRequestSort: (event: React.MouseEvent<unknown>, property: string) => void;
  order: Order;
  orderBy: string;
}

type DivisionDataProps = {
  id: number;
  name: string;
};
/* -------------------------------------------------------------------------- */

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

/* -------------------------- enchanced table head -------------------------- */
const headCells: readonly HeadCell[] = [
  {
    id: 'member_id',
    align: 'left',
    label: 'Member ID',
    isSort: true,
  },
  {
    id: 'name',
    align: 'center',
    label: 'Name',
    isSort: true,
  },
  {
    id: 'division',
    align: 'center',
    label: 'Divisi',
    isSort: false,
  },
  {
    id: 'limit',
    align: 'center',
    label: 'Limit',
    isSort: false,
  },
  {
    id: 'active',
    align: 'center',
    label: 'Status',
    isSort: true,
  },
];

function EnhancedTableHead({ order, orderBy, onRequestSort }: EnhancedTableProps) {
  const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => {
    onRequestSort(event, property);
  };

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

export default function TableList(props: any) {
  const { corporateValue } = useContext(UserCurrentCorporateContext);

  const [dataTable, setDataTable] = useState([]);
  const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
    current_page: 0,
    from: 0,
    last_page: 0,
    links: [],
    path: '',
    per_page: 0,
    to: 0,
    total: 0,
  });

  const [isLoading, setIsLoading] = useState(true);
  const [searchParams, setSearchParams] = useSearchParams();
  const [appliedParams, setAppliedParams] = useState({});

  const [order, setOrder] = useState<Order>('asc');
  const [orderBy, setOrderBy] = useState('name');
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(10);

  /* ------------------------------- handle sort ------------------------------ */
  const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => {
    const isAsc = orderBy === property && order === 'asc';
    setOrder(isAsc ? 'desc' : 'asc');
    setOrderBy(property);
    const params = Object.fromEntries([
      ...searchParams.entries(),
      ['order', isAsc ? 'desc' : 'asc'],
      ['orderBy', property],
    ]);
    setAppliedParams(params);
  };
  /* -------------------------------------------------------------------------- */

  /* ----------------------------- division field ----------------------------- */
  const [divisionValue, setDivisionValue] = useState('all');
  const [divisionData, setDivisionData] = useState([]);

  const handleDivisionChange = (event: SelectChangeEvent) => {
    setDivisionValue(event.target.value as string);

    if (event.target.value === 'all') {
      searchParams.delete('division');
      const params = Object.fromEntries([...searchParams.entries()]);
      setAppliedParams(params);
    } else {
      const params = Object.fromEntries([
        ...searchParams.entries(),
        ['division', event.target.value as string],
      ]);
      setAppliedParams(params);
    }
  };
  /* -------------------------------------------------------------------------- */

  /* ------------------------------ Search field ------------------------------ */
  const [searchText, setSearchText] = useState('');

  const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setIsLoading(true);
    if (searchText === '') {
      searchParams.delete('search');
      const params = Object.fromEntries([...searchParams.entries()]);
      setAppliedParams(params);
    } else {
      const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
      setAppliedParams(params);
    }
    await new Promise((resolve) => setTimeout(resolve, 500));
    setIsLoading(false);
  };
  /* -------------------------------------------------------------------------- */

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

  /* --------------------------- row page per limit --------------------------- */
  const onRowsPerPageChangeHandle = async (event: React.ChangeEvent<HTMLInputElement>) => {
    setIsLoading(true);
    searchParams.delete('page');
    const params = Object.fromEntries([
      ...searchParams.entries(),
      ['per_page', parseInt(event.target.value, 10)],
    ]);
    setRowsPerPage(parseInt(event.target.value, 10));
    await new Promise((resolve) => setTimeout(resolve, 500));
    setAppliedParams(params);
    setIsLoading(false);
  };
  /* -------------------------------------------------------------------------- */

  useEffect(() => {
    (async () => {
      setIsLoading(true);

      const division = await axios.get(`${corporateValue}/division`);
      setDivisionData(division.data);

      const params =
        Object.keys(appliedParams).length !== 0
          ? appliedParams
          : Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);

      const corporateMembers = await axios.get(`${corporateValue}/members`, {
        params: { ...params, claimMember: false },
      });

      setSearchParams(params);
      setDataTable(corporateMembers.data.data);
      setPaginationTable(corporateMembers.data);
      setRowsPerPage(corporateMembers.data.per_page);
      setIsLoading(false);
    })();
  }, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]);

  return (
    <Card>
      <Grid container>
        {/* Field 1 */}
        <Grid item xs={12} paddingX="24px" paddingY="20px">
          <Grid container spacing={2}>
            <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={divisionValue}
                  label="Division"
                  onChange={handleDivisionChange}
                >
                  <MenuItem value="all">All</MenuItem>
                  {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={handleSearchSubmit}>
                <TextField
                  id="search-input"
                  label="Search"
                  variant="outlined"
                  onChange={(event) => setSearchText(event.target.value)}
                  value={searchText}
                  fullWidth
                />
              </form>
            </Grid>
          </Grid>
        </Grid>
        {/* End Field 1 */}
        {/* Field 2 */}
        <Grid item xs={12}>
          <TableContainer component={Paper}>
            <Table aria-label="collapsible table" size="small">
              <EnhancedTableHead
                order={order}
                orderBy={orderBy}
                onRequestSort={handleRequestSort}
              />
              <TableBody>
                {isLoading ? (
                  <TableRow>
                    <TableCell colSpan={6} align="center">
                      Loading . . .
                    </TableCell>
                  </TableRow>
                ) : dataTable.length >= 1 ? (
                  dataTable.map((row: DataTableProps, index) => (
                    <TableRow key={index}>
                      <TableCell align="left">{row.memberId}</TableCell>
                      <TableCell align="center">{row.fullName}</TableCell>
                      <TableCell align="center">{row.division}</TableCell>
                      <TableCell align="center" width={170}>
                        <Stack>
                          <BorderLinearProgress
                            variant="determinate"
                            value={row.limit.percentage}
                            sx={{ mb: 1 }}
                          />
                          <Typography sx={{ typography: 'caption', color: '#637381' }}>
                            {fSplit(row.limit.current)} / {fSplit(row.limit.total)}
                          </Typography>
                        </Stack>
                      </TableCell>
                      <TableCell align="center">
                        {row.status === 1 ? (
                          <Button
                            sx={{
                              backgroundColor: 'rgba(84, 214, 44, 0.16)',
                              color: palette.dark.success.dark,
                              paddingY: 0,
                              '&:hover': {
                                backgroundColor: 'rgba(84, 214, 44, 0.32)',
                                color: palette.dark.success.darker,
                              },
                            }}
                          >
                            Active
                          </Button>
                        ) : (
                          <Button
                            sx={{
                              backgroundColor: 'rgba(255, 72, 66, 0.16)',
                              color: palette.dark.error.dark,
                              paddingY: 0,
                              '&:hover': {
                                backgroundColor: 'rgba(255, 72, 66, 0.32)',
                                color: palette.dark.error.darker,
                              },
                            }}
                          >
                            Inactive
                          </Button>
                        )}
                      </TableCell>
                      <TableCell align="right">
                        <IconButton>
                          <Iconify icon="ic:baseline-more-vert" />
                        </IconButton>
                      </TableCell>
                    </TableRow>
                  ))
                ) : (
                  <TableRow>
                    <TableCell colSpan={6} align="center">
                      No Data Found
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </TableContainer>

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