import React from 'react'
import {Typography, Paper, TableContainer, IconButton, Grid} from "@mui/material"
import {MdKeyboardArrowDown, MdKeyboardArrowUp} from "react-icons/md"
import { StyledTable, StyledTableBody, StyledTableRow, StyledTableCell, StyledTableHead, StyledTableFooter } from './styles'
import Progress from '../Progress';

interface Cols{
  columnKey ?: string,
  columnLabel ?: string | React.ReactNode,
  minWidth?: number,
  style?: React.CSSProperties,
  render ?: (row : any,index:any) => React.ReactNode
}

interface TableProps{
  cols ?: Array<Cols>,
  data ?: Array<object>, 
  isExpandable ?: boolean, 
  expandCols ?: Array<object>, 
  expandLabelKey?: string,
  preloading ?: boolean,
  className ?: string,
  onExpand ?: (row : object, id : string) => void,
  sx?: any,
  isPagination?: boolean,
  page?: number,
  rowsPerPage?: number,
  tableContainerStyles?:any,
  childTableStyles?:any,
  childLoading?:boolean
}

interface TableHeaders{
  cols : Array<Cols>,
  isExpandable : boolean
}

interface TableBodyRow{
  row ?: {[key : string] : any},
  cols ?: Array<Cols>,
  isExpandable ?: boolean,
  expandCols ?: Array<Cols>,
  expandLabelKey?:string,
  index?:number,
  onExpand ?: (row : object, id : string) => void,
  childTableStyles:any,
  childLoading?:boolean
}

const getTableHeaders = ({cols, isExpandable} : TableHeaders) => {
  return <StyledTableRow>
      {isExpandable && <StyledTableCell sx={{width: "15px"}} />}
      {cols?.map((header, index) => <StyledTableCell id={String(index)} key={`th-${index}`} style={header?.style}>
          <Typography component={"span"} fontWeight={550}>{header?.columnLabel}</Typography>
      </StyledTableCell>)}
  </StyledTableRow>
}

const  TableBodyRow = ({row = {}, cols = [], isExpandable, expandCols, childTableStyles,childLoading,expandLabelKey,index,onExpand = () => {/* */}} : TableBodyRow) =>  {
  const [isExpand, setIsExpand] = React.useState(false);
  const [loader, setLoader] = React.useState(false);
  const onExpandClick = async (id : string) => {
        let interval: NodeJS.Timer;
        let timer: NodeJS.Timeout;
        setIsExpand(!isExpand)
        if(!isExpand && expandLabelKey){
            setLoader(true);
            await onExpand(row, id);
            timer = setTimeout(() => {
              interval = setInterval(() => {
                if(expandLabelKey && row?.[expandLabelKey]?.length > 0){
                  setLoader(false)
                  clearInterval(interval);
                  clearTimeout(timer);
                }  
              }, 500)
              setLoader(false);
              clearTimeout(timer);
            }, 1500);
        }
    }
  return (
    <React.Fragment>
      <StyledTableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
        {isExpandable && <StyledTableCell>
          <IconButton
            aria-label="expand row"
            size="small"
            onClick={() => onExpandClick(row?.definitionId)}
          >
            {isExpand ? <MdKeyboardArrowUp /> : <MdKeyboardArrowDown />}
          </IconButton>
        </StyledTableCell>}
        {
          cols.map((col,key) => {
            return(
              <StyledTableCell key={key} style={{ minWidth: col?.minWidth, ...col?.style }}>{col.render!(row,index)}</StyledTableCell>
            )
          })
        }
      </StyledTableRow>
      {(isExpandable && isExpand) && (loader ? 
            <StyledTableRow data-action="expandable-row">
                <StyledTableCell colSpan={cols?.length + 1}>
                    <div style={{height : "80px", display : "flex", justifyContent : "center",alignItems : "center"}}>
                    <Grid container direction="row" justifyContent="center" alignItems="center">
                  <Progress />   
                  </Grid>
                    </div>
                </StyledTableCell>
            </StyledTableRow> :
            <StyledTableRow>
              <StyledTableCell colSpan={cols.length+1}>
                <Table
                  {...{
                    cols: expandCols,
                    data: expandLabelKey ? row?.[expandLabelKey] : [],
                    isExpandable: false,
                    isPagination: false,
                    preloading:childLoading,
                    tableContainerStyles:{
                    ...childTableStyles
                    }
                  }}
                />
              </StyledTableCell>  
            </StyledTableRow>
      )}
    </React.Fragment>
  );
}

const Table = (tableProps : TableProps) => {
  const {cols = [], data = [], childTableStyles,isExpandable = false, tableContainerStyles,expandCols, expandLabelKey, onExpand,  preloading, childLoading, sx, isPagination, page=0, rowsPerPage=0} = tableProps;
  return (
      <TableContainer
      component={Paper}
      sx={{
        ...tableContainerStyles
      }}
    >
      <StyledTable
        sx={{ ...sx, minWidth:650}}
        aria-label="collapsible table"
      >
        <StyledTableHead>
          {getTableHeaders({cols, isExpandable})}
        </StyledTableHead>
        <StyledTableBody>
          {preloading ? 
            <StyledTableRow>
              <StyledTableCell colSpan={cols?.length+1}>
                  <Grid container direction="row" justifyContent="center" alignItems="center">
                  <Progress />   
                  </Grid>
              </StyledTableCell>
            </StyledTableRow> :
            <>
              {
                data.length > 0 ? <>
                 {data.map((row,index) => (
                    <TableBodyRow key={index} {...{row, cols,childTableStyles, isExpandable, expandCols, expandLabelKey, onExpand,index,childLoading}} />
                  ))}
                </> : 
                  <StyledTableRow>
                      <StyledTableCell colSpan={cols?.length+1}>
                      <Typography sx={{height : "40px", textAlign: "center"}}>
                        No Records Found
                      </Typography>
                      </StyledTableCell>
                  </StyledTableRow>
              }
            </>
          } 
        </StyledTableBody>
      </StyledTable>
    </TableContainer>    
  )
}

export default Table