import React, {useMemo, useCallback, useState, useEffect, useRef, useLayoutEffect} from 'react';
import * as Antd from 'antd'
import * as Shared from 'placeholder-shared'
import * as Common from './common'
import * as SC from './SComponents'
import * as Steps from './Steps2'
import * as Immer from 'immer'
import useResizeAware from 'react-resize-aware';
import {useSelector,useDispatch, connect} from 'react-redux'
var mysql = require('mysql')
import Knex from 'knex'
import * as  Icon  from '@ant-design/compatible';

export const RunButton = (props: {
    onRun:(e:React.MouseEvent) =>any;
    title:string;
}) => {
        return <SC.SButton className='BlueButton' onClick={props.onRun}>{props.title}</SC.SButton>
}

export class MySqlConnection {
    [Immer.immerable] = true
    constructor() {

    }
    connectionName:string='';
    hostName:string='';
    username:string=''
    password:string='';
    defaultSchema = '';
}

interface IDBColumns {
    columns:any[];
    builderTable:string;
}
export const DBSelect = (props:{currentStep:number,connection:MySqlConnection,operation:IDBColumns}) => {
    const {currentStep,connection,operation} = props
    const dispatch = useDispatch()
    const [columns, setColumns] = useState([])
    const [selectedKeys, setSelectedKeys] = useState([])
    const handleSelectChange= ((sourceSelected, targetSelected) => {
        setSelectedKeys([
            ...sourceSelected, ...targetSelected
        ]
        )
    })
    useEffect(() => {
        if (!operation.builderTable) {
            return;
        }
        RunMySQLQuery(connection, `SHOW columns from ${operation.builderTable}`).then((result) => {
            setColumns(result[0].map((c, index) => {
                return {
                    key: c.Field, title: c.Field
                }
            }
            ))
        })
    },[connection, operation])
    const handleChange = (nextTargetKeys, direction, moveKeys) => {
        dispatch(Shared.State.getUpdateStepOperationAction(currentStep,
            'columns', nextTargetKeys, true))
    }
    return <Common.DivWithClassName className='flexGrow'>  <Antd.Transfer
        listStyle={{height:'400px'}}
        dataSource={columns}
        titles={[operation.builderTable, 'query']}
        targetKeys={operation.columns}
        selectedKeys={selectedKeys}
        onChange={handleChange}
        onSelectChange={handleSelectChange}
        render={(item) => {
            return item.title}
        }
    />
    </Common.DivWithClassName>
}
const GetMySqlConnection = (connection:MySqlConnection) => {
    return mysql.createConnection({
        supportBigNumbers: true,
        host: connection.hostName,
        user: connection.username,
        password: connection.password,
        database: connection.defaultSchema
    });
}
export const RunMySQLQuery = (connection:MySqlConnection,query:string) => {
    var c = GetMySqlConnection(connection)
    var knex = Knex({
        client: 'mysql'
    });
    return new Promise((resolve,reject) => {
        console.log("running query", connection, query)
        knex.raw(query).connection(c).then((rows) => {
            console.log(rows)
            resolve(rows)
            c.end()
        }).catch((e) =>{c.close();reject(e)})
    })
}
const ConfigureMySQL = (props: {onCancelCB:(e:React.MouseEvent) => any, onOkCB:(MySqlConnection) =>any, visible:boolean, mySqlConnection:MySqlConnection}) =>  { 
    const {mySqlConnection, visible, onCancelCB, onOkCB} = props;
    const [sqlConnectionScratch, setConnection] = useState(mySqlConnection)
    const getEditMySqlConnection= (key:string) => {
        return (e:any) => {
            setConnection({
                ...sqlConnectionScratch, 
                [key]: e.target.value
            })
        }
    }
    const myOnOkCB = (e:React.MouseEvent) => {
        onOkCB(sqlConnectionScratch)
    }
    return  <Antd.Modal visible={visible} onCancel={onCancelCB} onOk={myOnOkCB} title={'Configure MySql Connection'}>
        <SC.SInputWithLabel onChange={getEditMySqlConnection('connectionName')} label='Connection Name' value={sqlConnectionScratch.connectionName}></SC.SInputWithLabel>
        <SC.SInputWithLabel onChange={getEditMySqlConnection('hostName')} label='Hostname' value={sqlConnectionScratch.hostName}></SC.SInputWithLabel>
        <SC.SInputWithLabel onChange={getEditMySqlConnection('username')} label='Username' value={sqlConnectionScratch.username}></SC.SInputWithLabel>
        <SC.SInputWithLabel onChange={getEditMySqlConnection('password')} label='Password' value={sqlConnectionScratch.password}></SC.SInputWithLabel>
        <SC.SInputWithLabel onChange={getEditMySqlConnection('defaultSchema')} label='Default Schema' value={sqlConnectionScratch.defaultSchema}></SC.SInputWithLabel>
    </Antd.Modal>
}

export const ConfigureDBConnection = (props:{}) => {
    const connections = useSelector ((state:any) => {
        return (state as any).connections;
    })
    const runState = useSelector(Shared.RunState.getRunState)
    const currentStep = useSelector((state:any) => {
        return state.currentStep;
    })
    const [mySql, setEditMySQL] = useState(false)
    const dispatch = useDispatch()
    const onNewMySQL = (e) => {
        setEditMySQL(true)
    }
    let connectionItems = []
    for (let c in connections) {
        connectionItems.push(<Antd.Menu.Item key={c} onClick={
            (e) => {
                dispatch(Shared.State.getUpdateStepOperationAction(currentStep, 
                   'connectionID', c, true))
            }
        }>{connections[c].connectionName}</Antd.Menu.Item>)
    }
    const menu = <Antd.Menu>
        {connectionItems}
            
            <Antd.Menu.SubMenu title='New DB Connection'>
                {/*}
                <Antd.Menu.Item onClick={onNewMySQL}>Google Cloud SQL</Antd.Menu.Item>
*/}
                <Antd.Menu.Item onClick={onNewMySQL}>MySQL</Antd.Menu.Item>
                {/*}
                <Antd.Menu.Item onClick={onNewMySQL}>PostgresSQL</Antd.Menu.Item>
*/}
            </Antd.Menu.SubMenu>
        </Antd.Menu>

    const onCancelCB = (e: React.MouseEvent) => {
        setEditMySQL(false)
    }
    const onOkCB= (newConnection) => {
        setEditMySQL(false)
        //const newConnectionID = Shared.Data.getNextID(Shared.Data.IDType.connection)
        //dispatch(Shared.State.getNewConnection(newConnectionID, newConnection))
        //dispatch(Shared.State.getUpdateStepOperationAction(currentStep,
            //'connectionID', newConnectionID, true))
    }

    return <Common.DivWithClassName>
        <Antd.Dropdown.Button overlay={menu}>
            <span>
                {runState.currentStepData.operation.connectionID && 
                connections[runState.currentStepData.operation.connectionID].connectionName || 
                'Configure DB Connection'
                }<Icon.Icon type="down" />
            </span>
        </Antd.Dropdown.Button>
        {mySql &&
            <ConfigureMySQL onCancelCB={onCancelCB} onOkCB={onOkCB} visible={mySql} mySqlConnection={new MySqlConnection()} />
        }
    </Common.DivWithClassName>
}