import React, { useState, useEffect, useCallback ,useMemo} from 'react';

import { connect, useSelector,useDispatch } from 'react-redux'
import * as Shared from 'placeholder-shared'
import * as Antd from 'antd'
import { Link, Redirect, withRouter } from 'react-router-dom'
//import * as Common from './common'
import './Login.scss';
import './common.scss';
import * as Task from './Task'

import { Form, Input, Button, Layout, Row, Col, message, Space, Typography, Card } from 'antd';

import * as Cognito from './Cognito';
import * as Common from './common'
import * as AWSSdk from 'aws-sdk';
import * as Lineage from './Lineage'
import {
    CheckOutlined,
    PlusOutlined,
	NumberOutlined,
	GoogleOutlined,
	MailOutlined,
    LockOutlined,
    DownOutlined,
    ToolOutlined
} from '@ant-design/icons';

export const LineageTag = (props:any) => {
    const {label, value, closable, onClose} = props
    return <Antd.Tag color='blue' closable={true} onClose={onClose}>
        {label}

    </Antd.Tag>

}
export const getLineageForSteps = (state, steps) => {
    let lineages = {}
    steps.forEach((s) => {
        Object.keys(Shared.Common.getValueSafe(state, ['steps', s, 'operation', 'lineageGroup'], {})).forEach((l) => {
            lineages[l] = true
        })
    })
    return Object.keys(lineages)
}

export const CreateLineageModal = (props) => {
    const createLineageGroupInfo = useSelector(state => (state as any).UIState.createLineageGroupModal)
    const dispatch = useDispatch()
    const [lineageGroupName, setLineageGroupName] = useState("")
    useEffect(() => {
        if (!createLineageGroupInfo)
            setLineageGroupName("")
    }, [createLineageGroupInfo])
    const onOK = () => {
        if (lineageGroupName.length){
            dispatch(Lineage.AddToLineageGroupThunk(lineageGroupName))
            dispatch(Shared.State.changeUIState('createLineageGroupModal', false))
        }
    }
    return <Antd.Modal visible={createLineageGroupInfo} title='Create Lineage Group'
        onCancel={() => {
            dispatch(Shared.State.changeUIState('createLineageGroupModal', false))
        }}
        okButtonProps={{disabled:lineageGroupName.length == 0}}
        onOk={onOK
        }>
        <Antd.Input onPressEnter={onOK} placeholder='New Lineage Group Name' value={lineageGroupName} onChange={(e)=> setLineageGroupName(e.target.value)}>
        </Antd.Input >
    </Antd.Modal>

}
export const AddToLineageGroupThunk = (lineageGroupName) => {
    return (dispatch, getState) => {

        const currentStepGraph = getState().currentStepGraph
        const stepsSelect = getState().stepsSelect
        const allHighlightedSteps = { [currentStepGraph]: true, ...stepsSelect }
        let allLineage = {}
        const gFinal = getState().edges.gFinal
        for (let stepCounter in allHighlightedSteps) {
            allLineage[parseInt(stepCounter)] = true;
            Task.getPredecessors(gFinal, parseInt(stepCounter)).forEach((s) => {
                allLineage[parseInt(s)] = true
            })
            Task.getSuccessors(gFinal, parseInt(stepCounter)).forEach((s) => {
                allLineage[parseInt(s)] = true
            })
        }
        dispatch(Shared.State.moveToLineageGroup(allLineage,[lineageGroupName]))
        dispatch(Shared.State.ShowAllModels())
        dispatch(Shared.State.toggleLineageGroup(lineageGroupName))
    }
}
export const LineageModal = (props) => {
    const dispatch = useDispatch()
    const visible = useSelector(state => (state as any).UIState.ManageLineageGroupsVisible)
    const lineageGroups = useSelector(state => (state as any).lineageGroups)
    const close = (e) => {
        dispatch(Shared.State.changeUIState("ManageLineageGroupsVisible", false))
    }
    const footer = () => {
        return <Common.DivWithClassName className='width100Percent rowFlexBox'>
            <Common.DivWithClassName className='flexStay floatRight rowFlexBox'>
                <Antd.Space direction='horizontal'>
                    <Antd.Button type='primary' onClick={(e:any)=> {
                        dispatch(Shared.State.newLineageGroupAction('New Lineage Group'))
                    }}><PlusOutlined />Create new Lineage Group</Antd.Button>
                </Antd.Space>
            </Common.DivWithClassName>
        </Common.DivWithClassName>
    }
    const data = useMemo(() => {
	    return !lineageGroups?[]:Object.keys(lineageGroups).map((lineageGroup) => {
            return {
                key: lineageGroup, name: lineageGroup
            }
        })
    }, [lineageGroups])
        return <Antd.Modal width={'95%'} visible={visible} title='Add/Edit Lineage Groups' onCancel={close} onOk={close} >
            <Common.DivWithClassName style={{ height: '65vh' }} className='columnFlexBox'>
                <span>Use lineage groups to group your graph into smaller sub-graphs. This can help organize data models into subject areas like Engineering, HR, Marketing.  </span>
                <br/>
                <Antd.Table bordered={true} columns={[{
                    title: 'Lineage Group Name',
                    dataIndex: 'name',
                    // eslint-disable-next-line react/display-name
                    render: (text) => {
                        return <Antd.Typography.Text editable={{
                            onChange: (newValue) => {
                                if (newValue != text)
                                    dispatch(Shared.State.changeLineageGroupName(text, newValue))
                            }
                        }}
                        >{text}</Antd.Typography.Text>
                    }
                },
                    {
                        title: 'Actions',
                        //dataIndex: 'name',
                        // eslint-disable-next-line react/display-name
                        render: (text) => {
                            return <Antd.Space direction='horizontal'><a onClick={() => {
                                dispatch(Shared.State.RemoveLineageGroup(text.name))
                            }}>
                                Delete</a></Antd.Space>
                        }
                }]}
                    showHeader={true} footer={footer} locale={{ emptyText: 'No Lineage Groups Configured' }} dataSource={data}>
                </Antd.Table>
            </Common.DivWithClassName>
        </Antd.Modal>
}
export const LineageControls =(props:{}) => {
    const dispatch = useDispatch()
    const lineageGroups = useSelector(state => (state as any).lineageGroups)

    const graphViewMode = useSelector(state => Shared.Common.getValueSafe(state, ['UIState', 'graphViewMode'], 'graph'))
    const menu = < Antd.Menu >
        {!lineageGroups ? [] : Object.keys(lineageGroups).map((k) => {
            return <Antd.Menu.Item
                onClick={(e) => {
                    dispatch(Shared.State.toggleLineageGroup(k))
                }}
                key={k}>
                {lineageGroups[k].show == true && <CheckOutlined />
                }{k}
            </Antd.Menu.Item>
        })}
        <Antd.Menu.Item onClick={
            (e) => {
                dispatch(Shared.State.ShowAllModels())
            }
        }>
            Show All Models
      </Antd.Menu.Item>
        <Antd.Menu.Divider />
        <Antd.Menu.Item onClick={
            (e) => {
                dispatch(Shared.State.changeUIState("ManageLineageGroupsVisible", true))
            }
        }>
           <ToolOutlined/> Manage Lineage Groups
      </Antd.Menu.Item>
        <Antd.Menu.Divider />
        <Antd.Menu.Item onClick={
            (e) => {
                dispatch(Shared.State.getSetCurrentStepGraph(0))
                dispatch(Shared.State.changeUIState("createLineageGroupModal", true))
            }
        }>
           <PlusOutlined/>Create new Lineage Group
      </Antd.Menu.Item>
    </Antd.Menu >
    const viewMenu = <Antd.Menu>
        <Antd.Menu.Item onClick={
            (e) => {
                dispatch(Shared.State.changeUIState('graphViewMode', 'graph'))
            }
        }>
            {graphViewMode == 'graph' && <CheckOutlined />} Graph
        </Antd.Menu.Item>
        <Antd.Menu.Item onClick={
            (e) => {
                dispatch(Shared.State.changeUIState('graphViewMode', 'datasets'))
            }
        }>
            {graphViewMode == 'datasets' && <CheckOutlined />} Datasets
        </Antd.Menu.Item>
    </Antd.Menu>
    const [visible, setVisible] = useState(false)
    const [visible2, setVisible2] = useState(false)
    const onVisibleChange = useCallback((visible) => {
        setVisible(visible)
    },[setVisible])
    const onVisibleChange2 = useCallback((visible) => {
        setVisible2(visible)
    },[setVisible2])
	const showingLineageGroups = !lineageGroups?[]:Object.keys(lineageGroups).map((l) => {
        return lineageGroups[l].show ? l : false
    }).filter(s => !!s)
    return <Common.DivWithClassName className='rowFlexBox paddingRight20px'>
        <Antd.Space>
            <Antd.Typography.Text >Show Graph</Antd.Typography.Text>
            <Antd.Switch checked={graphViewMode == 'graph'} onChange={(checked) => {
                dispatch(Shared.State.changeUIState('graphViewMode', checked ? 'graph' : 'datasets'))
            }} />
            {graphViewMode == 'graph' &&
                <Common.DivWithClassName className='rowFlexBox alignItemsCenter'>
                    <Common.DivWithClassName key='Divider2' className='rowFlexBox marginRight10px height100Percent VerticalDivider'></Common.DivWithClassName>
                <Antd.Space direction='horizontal'>
                    <Antd.Typography.Text strong>Viewing: </Antd.Typography.Text>
                    <Antd.Dropdown trigger={['hover']} overlay={menu} visible={visible} onVisibleChange={onVisibleChange}
                    >
                        <a className='ant-dropdown-link rowFlexBox alignItemsCenter'>
                            {showingLineageGroups.length != 0 && showingLineageGroups.join(",")}
                            {showingLineageGroups.length == 0 && 'All Models'}
                            <DownOutlined style={{ fontSize: '9px' }} />
                        </a>
                    </Antd.Dropdown>
                </Antd.Space>
                </Common.DivWithClassName>
            }
            <LineageModal />
        </Antd.Space>
    </Common.DivWithClassName>
}
