import React, {useMemo, useCallback, useState, useEffect, useRef, useLayoutEffect} from 'react';
import {batch, shallowEqual,connect, useSelector, useDispatch} from 'react-redux'
import * as TaskHeader from './TaskHeader'
import * as Shared from 'placeholder-shared'
import * as Immer from 'immer'
import * as Drag from './Drag'
import * as Data from './Data'
import * as Common from './common'
import * as Step from './Step'
import * as Steps2 from './Steps2'
import * as Palette from './Palette'
import * as Task from './Task'
import useResizeAware from 'react-resize-aware';
import * as Settings from './Settings'
import * as CreateTask from './CreateTask'
import * as ModelViewer from './ModelViewer'
import * as VersionControl from './VersionControl'
import * as SQLStepMenu from './SQLStepMenu'
import * as StepMenu from './StepMenu'

import * as Antd from 'antd'

export const DatasetTypes = (props:{stepCounter:number}) => {
    const {stepCounter} = props;
    const stepData = useSelector(state => (state as any).steps[stepCounter])
    const runResults = useSelector(state => (state as any).runResults[stepCounter])
    const fields = Shared.Common.getValueSafe(runResults, ['previewResult', 'fields'], [])
    return <Common.DivWithClassName className='height150px' style={{'textAlign':'left'}}>
        <Common.DivWithClassName className='positionRelative overflowYScroll overflowXHidden height100Percent width100Percent'>
            <Common.DivWithClassName className='positionAbsolute width100Percent'>
                {fields.map((f) => {
                    return <Common.DivWithClassName key={f.name} className='font1'>{f.name}</Common.DivWithClassName>
                })}
            </Common.DivWithClassName>
        </Common.DivWithClassName>
    </Common.DivWithClassName>

}
export const DatasetCard = (props:{stepCounter:number}) => {
    const gridStyle:any = {
        width: '20%',
        textAlign: 'center',
    };
    const {stepCounter} = props;
    const stepData = useSelector(state => (state as any).steps[stepCounter])
    const stepName = useSelector(state => Shared.Runner.getName(stepData))
    return <Antd.Card.Grid key={stepCounter} style={ gridStyle }>
        <Antd.Card type='inner' title={<span className='font1'>{stepName}</span>}>
            <DatasetTypes stepCounter={stepCounter}/>
        </Antd.Card>
        </Antd.Card.Grid>

}

export const DatasetGrid = (props: {}) => {
    const treeData = useSelector(state =>
        (state as any).treeData[1])
    const steps = useSelector(state =>
        (state as any).steps)
    const selectedKeys = useSelector(state => Shared.Common.getValueSafe(state, ['UIState', 'datasetsSelectedKeys'], []))
    const lineageGroups = useSelector(state => (state as any).lineageGroups)
    let content = null
    if (!selectedKeys.length){
        content = null
    }
    else{ 
        if (selectedKeys[0] == 'Unassigned Models'){
            const cards = []
            Shared.TreeData.forAllStepsInTask(treeData, steps, (stepCounter, stepData) => {
                cards.push(<DatasetCard key={stepCounter} stepCounter={stepCounter} />)
            })
            content = <Antd.Card className='flexGrow height100Percent' title="Unassigned Models">
                {cards}
            </Antd.Card>
        }
        else if (selectedKeys[0].startsWith('lineage')) {
            const lineage = selectedKeys[0].split("-")[1]
            const cards = []
            Object.keys(lineageGroups[lineage].steps).forEach((s) => {
                   cards.push(<DatasetCard key={parseInt(s)} stepCounter={parseInt(s)} />)
            })
            content = <Antd.Card className='flexGrow height100Percent' title={lineage}>
                {cards}
            </Antd.Card>
        }
        else if (selectedKeys[0].startsWith('step')) {
            const stepCounter = parseInt(selectedKeys[0].split("-")[1])
            content = <Data.StateDataView stepCounter={stepCounter} height="100%" width="100%" />
        }
    }
    return <Common.DivWithClassName className='positionRelative height100Percent width100Percent overflowYScroll'>
        <Common.DivWithClassName className='positionAbsolute height100Percent width100Percent '>
            {content}
        </Common.DivWithClassName>
        </Common.DivWithClassName>
}

export const Datasets = (props:{}) => {
    return <Common.DivWithClassName className='rowFlexBox flexGrow height100Percent width100Percent'>
        <DatasetGrid/>
  </Common.DivWithClassName>
}

export const DatasetTree = (props: {}) => {
    const expandedKeys = useSelector(state => Shared.Common.getValueSafe(state, ['UIState', 'datasetsExpandedKeys'], []))
    const selectedKeys = useSelector(state => Shared.Common.getValueSafe(state, ['UIState', 'datasetsSelectedKeys'], []))
    const dispatch = useDispatch()
    const onSelect = (selectedKeys: any[],info:any) => {
        console.log("dataset on select", selectedKeys, info)
        dispatch(Shared.State.changeUIState('datasetsSelectedKeys', selectedKeys))
    }
    const onExpand = (expandedKeys: any[][]) => {
        dispatch(Shared.State.changeUIState('datasetsExpandedKeys', expandedKeys))
    }
    return (
        <Common.DivWithClassName className='flexStay300px borderRightBlack'>
            <Common.DivWithClassName className='positionRelative backgroundWhite height100Percent width100Percent'>
                <Common.DivWithClassName className='positionAbsolute overflowYScroll height100Percent width100Percent ModelViewerTree'>
                    <ModelViewer.Tree selectedKeys={selectedKeys}
                        expandedKeys={expandedKeys}
                        onSelect={onSelect}
                        onExpand={onExpand}
                        showDependencies={false}
                    /> </Common.DivWithClassName>)
        </Common.DivWithClassName>
        </Common.DivWithClassName>
    )
    const lineageGroups = useSelector(state => (state as any).lineageGroups)
    const treeData = useSelector(state =>
        (state as any).treeData[1])
    const steps = useSelector(state => 
        (state as any).steps)
    const treeDataNodes = useMemo(() => {
        let treeDataNodes =[]
        if (lineageGroups) {
            for (let l in lineageGroups) {
                let steps = lineageGroups[l].steps
                treeDataNodes.push({
                    title: l,
                    key: l,
                    children:
                        [...
                            Object.keys(steps).map((s) => {
                                return {
                                    title: s, key: s, isLeaf: true
                                }
                            })
                        ]
                })
            }
        }
        const leftOver =[]
        Shared.TreeData.forAllStepsInTask(treeData, steps, (stepCounter, stepData) => {
            if (!stepData.operation.lineageGroup){
                const name = Shared.Runner.getName(stepData)
                leftOver.push({
                    title: <span className='font2'>{name}</span>,
                    key: name, isLeaf: true
                })
            }
        })
        if (leftOver.length) {
            treeDataNodes.push({
                title:'Unassigned Models',
                key:'Unassigned Models', 
                children:leftOver
            })
        }

        return treeDataNodes
    }, [lineageGroups,steps,treeData])
    return <Common.DivWithClassName className='flexStay300px'>
        <Common.DivWithClassName className='positionRelative overflowYScroll height100Percent width100Percent'>
            <Common.DivWithClassName className='positionAbsolute'>
                <Antd.Tree.DirectoryTree expandAction={'doubleClick'} treeData={treeDataNodes} />
            </Common.DivWithClassName>
        </Common.DivWithClassName>
    </Common.DivWithClassName>
}