import React, {useMemo, useCallback, useState, useEffect, useRef, useLayoutEffect} from 'react';
import ReactDOM from 'react-dom'
import {   connect , useDispatch,useSelector} from 'react-redux'
import * as Common from './common'
import * as Shared from 'placeholder-shared'

import { HotTable } from '@handsontable/react';
import Handsontable from 'handsontable';
import * as Antd from 'antd'
import * as StepMenu from './StepMenu'

import useResizeAware from 'react-resize-aware';

import {
    LoadingOutlined,
} from '@ant-design/icons';
// Be sure to include styles at some point, probably during your bootstrapping
//import 'react-datasheet/lib/react-datasheet.css';
export const hotsettings={
    columnSorting:{
        indicator:true
    },
    data: null,
    width: '100%',
    height: '100%',
    //height: '320px',
    colWidths:125,
    rowHeaders: true,
    colHeaders:true, 
    wordWrap: false,
    licenseKey: 'non-commercial-and-evaluation',
    manualColumnResize: true,
}

export const getData = (filter:string[] | null,data: Shared.Runner.QueryResult) => {
    if (!data || !data.rows) {
        return [[],[]]
    }
    const filtered = (columnName:string) => {
        return filter && Object.keys(filter).length && !(columnName in filter)
    }
    const result = data.rows.map((r: Shared.Runner.QueryRow) => {
        return r.values.map((value,index) => {
            const columnName = data.fields[index].name
            if (filtered(columnName)){
                return null;
            }
            if (value == 'null') {
                return "<NULL>"
            }
            if (typeof (value) == 'object') {
                return JSON.stringify(value)
            }
            else {
                return value;
            }
        }).filter(f => f!== null)
    })
    const columns = data.fields.map((f,index) => {
        const columnName = data.fields[index].name
        if (filtered(columnName)) {
            return null;
        }
        return f.name
    }).filter(f => f!== null)
    return [result, columns]
}

const useGetActiveStepCounter = () => {
    
    const currentRunResultIndex = useSelector(state => (state as any).currentRunResultIndex)
    const runResultsHistory = useSelector(state => {
       
     return (state as any).runResultsHistory.history
    })
    if (!runResultsHistory.length)
        return 0;
    else
        return runResultsHistory[currentRunResultIndex]
}

type DataViewProps = {
    className?:string;
    stepCounter:number;
    height:any;
    width:any;
    filter?:string[]|null ;
}
export const ColumnSelector = (props: { stepCounter: number, filter: {string:any}, onClickFilter: (columnName: string) => any }
) => {
    const stepCounter = props.stepCounter
    const filter = props.filter
    const runResults = useSelector(state => (state as any).runResults[stepCounter])
    const previewResult:Shared.Runner.QueryResult = runResults.previewResult
    const tags = !(previewResult && previewResult.fields) ? [] : previewResult.fields.map((f) => {
        const columnChecked = f.name in filter 
        return <Common.DivWithClassName key={f.name} className='flexStay'><Antd.Tag color={columnChecked? "#108ee9":null} className={
            Common.classNames({
                columnChecked: columnChecked
            })
        }
            onClick={() => {props.onClickFilter(f.name)}}
            key={f.name}>{f.name}</Antd.Tag>
        </Common.DivWithClassName>
    })
    if (!previewResult || !previewResult.fields) {
        return null;

    }
    return <Common.DivWithClassName className='ColumnSelector rowFlexBox'>
        <Common.DivWithClassName className='positionRelative overflowAuto height100Percent width100Percent'>
        <Common.DivWithClassName className='positionAbsolute height100Percent width100Percent rowFlexBox flexWrap'>
            {tags}
        </Common.DivWithClassName>
</Common.DivWithClassName>
    </Common.DivWithClassName>
}

export const HotTableWrapper = (props: {
    settings:any, hotRef?:any
})=>{
    const {settings, hotRef} = props;
    return (<HotTable ref={hotRef} settings={settings}
        />)
}

export const getHotSettings = (data, colHeaders, width,height) => {
    return {
        ...hotsettings,
        data: data,
        colHeaders: colHeaders,
        width: width,
        height: height
    }
}

export const DataView = (props:DataViewProps) => {
    const activeStepCounter = props.stepCounter
    const filter = props.filter;
    const [dataToShow, setDataToShow] = useState([])
    const runResults = useSelector(state => (state as any).runResults)
    const activeTab = useSelector(state => (state as any).UIState.mainWindowActiveTab)
    const barSplit = useSelector(state => (state as any).UIState.barSplit)
    //const sqlTabState = useSelector(state => (state as any).sqlTabState);
    //const previewStepIndex = useSelector(state => (state as any).UIState.activePreviewStep)


    const [resizeListener, size] = useResizeAware()
	const sqlCollapsed = useSelector(state => Shared.Common.getValueSafe(state, ['modelViewerState', activeStepCounter, 'sqlCollapsed'], false))
    const hotRef = useRef(null)
    const thisHotSettings = useMemo(() => {
        return getHotSettings(dataToShow[0], dataToShow[1], size.width, size.height)
    }, [dataToShow,props.width,props.height, size.height, size.width])
    useEffect(() => {
        const previewResults = Shared.Common.getValueSafe(runResults[activeStepCounter],['previewResult'], null);
        const data = getData(filter, previewResults);
        setDataToShow(data)
    }, [activeStepCounter, runResults,filter])
    useEffect(() => {
        if (hotRef.current) {
            hotRef.current.hotInstance.render()
        }
    }, [activeStepCounter, activeTab, runResults, barSplit, sqlCollapsed])
    const dispatch = useDispatch()
    const isRunning = Shared.Common.getValueSafe(runResults,[activeStepCounter, 'status'],null) == 'running' //whatever is active
    const runPreview = useCallback(() => {
        dispatch(Shared.Runner.runStepPreview(activeStepCounter))
    },[dispatch, activeStepCounter])
    const noData = !dataToShow.length || (!dataToShow[1].length)
    const noRows = dataToShow.length && (!dataToShow[0].length)
    
    return (
        <Common.DivWithClassName style={{width:props.width,height:props.height}} className={
            Common.classNames({
                zIndexZero: true,
                [props.className]: props.className,
                rowFlexBox: true
            })
        }>
            <Common.DivWithClassName className='rowFlexBox flexGrow width100Percent height100Percent'>
                {resizeListener}
                {((!isRunning && noRows)  || (!isRunning && noData)) && <Antd.Empty image={Antd.Empty.PRESENTED_IMAGE_SIMPLE} className='justifySelfCenter flexGrow alignSelfCenter minHeightZero overflowHidden' description={<><Antd.Button onClick={runPreview} size='small' type='link'>Run Preview</Antd.Button>to see data.</>}> </Antd.Empty>}
                {isRunning && <Common.DivWithClassName className='flexGrow rowFlexBox backgroundGrey1 alignItemsCenter justifyContentCenter'><LoadingOutlined style={{ fontSize: '80px' }} />
                </Common.DivWithClassName>
                }
                {!isRunning && !noData && !noRows &&  activeStepCounter != 0 && 
                    <HotTableWrapper 
                    hotRef={hotRef}
                        settings={thisHotSettings as any}
                    />
                }
            </Common.DivWithClassName>
        </Common.DivWithClassName>
    )
}

export const RunList = (props: { className }) => {
    const { className } = props;
    const dispatch = useDispatch()
    const runResults = useSelector(state => (state as any).runResults)
    const runResultsPending = useSelector(state => (state as any).runResultsHistory).pending
    const runResultsHistory = useSelector(state => (state as any).runResultsHistory).history
    const currentRunResultIndex = useSelector(state => (state as any).currentRunResultIndex)
    const steps = useSelector(state => (state as any).steps)
    const activeStepCounter = runResultsHistory[currentRunResultIndex]
    let activeStepName = null
    if (activeStepCounter)
        activeStepName = Shared.Runner.getName(steps[activeStepCounter])

    return <Common.DivWithClassName style={{outline:'none'}} className={
        Common.classNames({
            'flexStay200px': true,
            'rowFlexBox': true,
            'positionRelative': true,
            'RunList':true,
        })}
    >
        <Common.DivWithClassName className='positionAbsolute height100Percent width100Percent'>
            <Common.DivWithClassName className='overflowYScroll height100Percent'>
                {[].map((stepCounter, index) => {
                    const stepName = Shared.Runner.getName(steps[stepCounter])
                    return <Common.DivWithClassName
                        onClick={() => {
                            //dispatch(Shared.State.getSetCurrentRunResultIndex(index))
                            //TODO

                        }}
                        className={
                            Common.classNames({
                                ActiveRunResult: index == currentRunResultIndex,
                                flexGrow: true
                            })
                        }>
                        <LoadingOutlined />

                        {stepName}
                    </Common.DivWithClassName>
                })
                }
                {runResultsHistory.map((stepCounter, index) => {
                    const stepName = Shared.Runner.getName(steps[stepCounter])
                    return <Common.DivWithClassName
                        onClick={() => {
                            dispatch(Shared.State.getSetCurrentRunResultIndex(index))

                        }}
                        className={
                            Common.classNames({
                                ActiveRunResult: index == currentRunResultIndex,
                                flexGrow: true
                            })
                        }>
                        {stepName}
                    </Common.DivWithClassName>
                })
                }
            </Common.DivWithClassName>
        </Common.DivWithClassName>
    </Common.DivWithClassName>
}

export const StateDataView = DataView

const Label = (props:{className:string, text:string, detail:string}) => {
    const {className, text,detail} = props
    return <Common.DivWithClassName className={
        Common.classNames({
            rowFlexBox: true,
            flexGrow: true,
            [className]: className
        })}
    >
        <Common.DivWithClassName className='marginRight10px'>
            {text}
        </Common.DivWithClassName>
        < Common.DivWithClassName className='LabelDetail floatRight font3 alignSelfCenter' >
            {detail}
        </Common.DivWithClassName >
    </Common.DivWithClassName>
}
export const DataViewer = (props: { showStepOnly?: boolean; stepCounter: number }) => {
    const currentStepCounter = props.stepCounter;
    const showStepOnly = props.showStepOnly
    //const previewStepIndex =  useSelector(state => (state as any).UIState.previewStepIndex);
    const steps = useSelector(state => (state as any).steps);
    const sqlTabActiveIndex = useSelector(state => (state as any).sqlTabActiveIndex);
    const activeIndex = !showStepOnly && (sqlTabActiveIndex[currentStepCounter]) ? sqlTabActiveIndex[currentStepCounter] : currentStepCounter; 
    return <Common.DivWithClassName className='columnFlexBox topBorderBlack DataView backgroundWhite zIndex1 width100Percent'>
        {/*}
        <Antd.Tabs tabBarGutter={0} type='card' size='small' tabPosition='left' className='flexGrow rowFlexBox DataTabs zIndex1' >
            <Antd.Tabs.TabPane className='floatRight' style={{ padding: '0' }} tab={<Label className='width100Percent rowFlexBox' text='Results' detail='' />} key='Results'>

*/}
{/*}
        <Antd.Breadcrumb>
            <Antd.Breadcrumb.Item>
                {Shared.Runner.getName(steps[activeIndex])}
            </Antd.Breadcrumb.Item>
        </Antd.Breadcrumb>
*/}
        <Common.DivWithClassName className='flexGrow rowFlexBox width100Percent'>

            <StateDataView className='flexGrow' width={'200px'} height={300} stepCounter={activeIndex} />
            {/*<StateDataView className='flexGrow' width={'100%'} height={220} stepCounter={previewStepIndex} />*/}
            {/*<StateDataView className='flexGrow' width={'100%'} height={220} stepCounter={currentStepCounter} />*/}
        </Common.DivWithClassName>
                {/*}
            </Antd.Tabs.TabPane>
            <Antd.Tabs.TabPane style={{ padding: '0' }} tab={<Label className='width100Percent' text='History' detail='' />} key='History' className='rowFlexBox RunListTab'>
                <RunList className='flexStay' />
                <Common.DivWithClassName className='overflowAuto flexGrow rowFlexBox width100Percent'>
                    <StateDataView className='flexGrow' width={'100%'} height={220} stepCounter={historyStepCounter} />
                </Common.DivWithClassName>
            </Antd.Tabs.TabPane>
        </Antd.Tabs>
*/}
    </Common.DivWithClassName >
}
