import React, { useEffect, useState, useMemo } from "react"
import PropTypes from 'prop-types'
import { TableHeader, Pagination, Search, TableRow } from "./additional-addons"

import WithSpinner from '../utility/hoc/spinner/with-spinner.component'
import useWindowDimensions from '../utility/effects/use-window-dimension-fetch.effect'
import './styles/data-table.styles.scss'
import variables from './styles/_variables.module.scss'
const DATATABLE_ITEMS_PER_PAGE = 50

const DataTable = ( { 
    totalItems = 0,
    itemsPerPage = DATATABLE_ITEMS_PER_PAGE,
    showControlsPerRow = false , headers, isLoading, showRowLoading = false,
    rowFormatters, idField,rowMenu, data, workingAtRow = -1,
    onPageChangeHandler = () => {}
}) => {
    
    const [currentPage, setCurrentPage] = useState(1)
    const [search, setSearch] = useState("")
    const [sorting, setSorting] = useState({ field: "", order: "" })
    const [expandedRows, setExpandedRows] = useState(new Set())

    const windowDimensions = useWindowDimensions()

    const visibleColumCount = () => {
        const { smBreakPoint, mdBreakPoint, lgBreakPoint,
            smVisibleColumns, mdVisibleColumns, lgVisibleColumns
        } = variables
        
        if (window.matchMedia(`(max-width: ${smBreakPoint})`).matches) return parseInt(smVisibleColumns)
        if (window.matchMedia(`(max-width: ${mdBreakPoint})`).matches) return parseInt(mdVisibleColumns)
        if (window.matchMedia(`(max-width: ${lgBreakPoint})`).matches) return parseInt(lgVisibleColumns)

    }


    useEffect(() => {
        
        // console.log('vars ',variables)
        // console.log('dimension =>',windowDimensions)

    }, [windowDimensions])

    const cachedData = useMemo(() => {
        let computedData = data

        if (search) {
            computedData = computedData.filter(
                comment =>
                    comment.name.toLowerCase().includes(search.toLowerCase()) ||
                    comment.email.toLowerCase().includes(search.toLowerCase())
            )
        }


        //Sorting comments
        if (sorting.field) {
            const reversed = sorting.order === "asc" ? 1 : -1
            computedData = computedData.sort(
                (a, b) =>
                    reversed * a[sorting.field].localeCompare(b[sorting.field])
            )
        }

        return computedData
        /* 
        //Local cached page slice: Current Page slice
        return computedData.slice(
            (currentPage - 1) * ITEMS_PER_PAGE,
            (currentPage - 1) * ITEMS_PER_PAGE + ITEMS_PER_PAGE
        )
        */
    }, [data,  search, sorting])

    const pageChanged = (pageNum) => {
        onPageChangeHandler(pageNum)
        setCurrentPage(pageNum)

    }


    const expandRow = e => {
        const targetRow = parseInt(e.target.dataset.row)
        const anotherSet = new Set(expandedRows)
        if(expandedRows.has(targetRow)){
            anotherSet.delete(targetRow)
        }else{
            anotherSet.add(targetRow)
        }        
        setExpandedRows(anotherSet)
    }

    const Table = ({records, headers}) => (
        <table className="datatable table table-striped ">
            <TableHeader
                headers={headers}
                onSorting={(field, order) =>
                    setSorting({ field, order })
                }
                controlsField={showControlsPerRow}
            />
            <tbody>
                { 
                records.map( (record, localIndex) => 
                            (<React.Fragment key={record[idField]}>
                                <TableRow idkey={record[idField]}
                                    visibleColumnCount={visibleColumCount() ?? headers.length}
                                    expanded={expandedRows.has(localIndex)}
                                    rowIndex={localIndex}
                                    rowIsLoading={showRowLoading}
                                    onExpandRow={expandRow} 
                                    actionColumn={showControlsPerRow}
                                    rowFormatters={rowFormatters}
                                    rowMenu={rowMenu}
                                    workingAtRow={workingAtRow}
                                    dataColumnCount={headers.length}
                                    columnNamesInOrder={headers.map(val => ({
                                        label: val.name,
                                        field: val.field
                                    }))}
                                />              
                                  
                            </React.Fragment>)
                        )                                          
                }
            </tbody>
        </table>
    )

    const TableWithSpinner = WithSpinner(Table)

    return (
        <>
            <div className="row my-3">
                <div className="col-md-6">
                    <Pagination
                        total={totalItems}
                        itemsPerPage={itemsPerPage}
                        currentPage={currentPage}
                        onPageChange={page => pageChanged(page)}
                    />
                </div>
                <div className="col-md-6 d-flex flex-row-reverse">                    
                    {/* <Search
                        onSearch={value => {
                            setSearch(value)
                            setCurrentPage(1)
                        }}
                    /> */}
                </div>
            </div>

            <div className="row">
                <div className="col">  
                {
                    totalItems === 0 && !isLoading ?
                        <h4>No records found</h4>
                        :
                        <TableWithSpinner isLoading={isLoading} records={cachedData} headers={headers}/>
                    
                }          
                </div>
            </div>
        </>
    )
}

DataTable.propTypes = {
    isLoading: PropTypes.bool,
    showControlsPerRow: PropTypes.bool,    
    rowFormatters: PropTypes.arrayOf(
        PropTypes.func.isRequired        
    ).isRequired,
    idField: PropTypes.string.isRequired,
    data: PropTypes.arrayOf(
        PropTypes.object
    ).isRequired,
    headers: PropTypes.arrayOf(
        PropTypes.shape({
            name: PropTypes.string,
            field: PropTypes.string,
            sortable: PropTypes.bool,
        })
    ).isRequired
}

DataTable.defaultProps = {
    showControlsPerRow: false,
    isLoading: false
}

export default DataTable
