import React, {useMemo, useCallback, useState, useEffect, useRef, useLayoutEffect} from 'react';
import {batch, shallowEqual,connect, useSelector, useDispatch} from 'react-redux'
import * as Common from './common'
import * as Shared from 'placeholder-shared'
import * as Antd from 'antd'
import * as Data from './Data'
import * as Step from './Step'
import * as StepMenu from './StepMenu'
import ReactResizeDetector from 'react-resize-detector';
import MonacoEditor from 'react-monaco-editor'
var beautify = require('js-beautify').js

import useDebouncedCallback from "use-debounce/lib/useDebouncedCallback";

export const getMaterializationCounter = (str:string) => {
    return str.split("-")[1]
}
export const ShowMaterializationThunk = (materializationCounter) => {
    return (dispatch, getState) => {
        dispatch(Shared.State.getShowStepAction(`materialization-${materializationCounter}`))
    }
}

export const useDocStringForMaterialization = () => {
    const materializations = useSelector(state => (state as any).materializations)
    const currentStep = useSelector(state => (state as any).currentStep)
    const currentStepData = useSelector(state => (state as any).steps[currentStep])
    const materializationHandlers = useSelector(state => (state as any).materializationHandlers)
    const mCounter = parseInt(currentStepData.operation.sqlType)
    if (!mCounter) {
        return null;
    }
    else {
        const docString = materializationHandlers[mCounter].docString
        return docString
    }
}

export const useHandlersForMaterialization = () => {
    const materializations = useSelector(state => (state as any).materializations)
    const currentStep = useSelector(state => (state as any).currentStep)
    const currentStepData = useSelector(state => (state as any).steps[currentStep])
    const materializationHandlers = useSelector(state => (state as any).materializationHandlers)
    const mCounter = parseInt(currentStepData.operation.sqlType)
    if (!mCounter) {
        return null;
    }
    else {
        const handlers = materializationHandlers[mCounter].handlers
        return handlers
        const handlerNames = Object.keys(handlers)
        return <><Antd.Button className='marginLeft5px' key={handlerNames[0]}>
            {handlerNames[0]}
        </Antd.Button>
            <Antd.Button key={handlerNames[1]}>
                {handlerNames[1]}
            </Antd.Button>
        </>
    }
}

export const useMaterializationOptions= ()=>  {
    const materializations = useSelector(state => (state as any).materializations)
    const currentStep = useSelector(state => (state as any).currentStep)
    const dispatch = useDispatch()
    const setMaterializationType = (mCounter: number) => {
        dispatch(Shared.State.getUpdateStepOperationAction(currentStep, 'sqlType',
            mCounter.toString(), false))
    }
    const components = useMemo(() => {
        return Object.keys(materializations).map((mCounter) => {
            return <Antd.Menu.Item key={mCounter} onClick={(e) => {
                setMaterializationType(parseInt(mCounter))
            }}>
                Create {materializations[mCounter].name}
            </Antd.Menu.Item>
        })
    }, [materializations,setMaterializationType])
    return components;
}

export const MaterializationEditor = (props:{className?:string}) => {
    const dispatch = useDispatch()
    const materializations = useSelector(state => (state as any).materializations)
    const materializationCounter = useSelector(state => getMaterializationCounter((state as any).currentStep))
    const materializationHandler= useSelector(state => (state as any).materializationHandlers[materializationCounter])
    const errorMessage = materializationHandler.error
    const materialization = materializations[materializationCounter]
    const materializationCode =materialization.code
    const name = materialization.name

    const nameRef = useRef(null)

    const {className} = props
	const [size, setSize] = useState({
		editorWidth: 0, editorHeight: 0
    })

	const editor = useRef(null)
	const editorDidMount = useCallback((editorToUse,monaco)=> {
		editor.current = editorToUse;
    }, [])

    const onResize = (width:number, height:number) => {

		//console.log("got resize", width, height)
		setSize({editorWidth:width, editorHeight:height})
		editor.current && editor.current.layout({width:width, height:height})
    }
    const onFocus=(e) => {

    }
    const onBlur = (e) => {

    }
    const onKeyUp = (e) => {

    }
    const onKeyPress = (e) => {

    }
    const onChange = (e)=> {
        dispatch(Shared.State.UpdateMaterialization(materializationCounter,
            'name',
            e.target.value
            ))
    }
    const onChangeCode = (newValue,e)=> {
        dispatch(Shared.State.UpdateMaterialization(materializationCounter, 'code',
            newValue
            ))
    }
    const onFormat = () => {

        const newCode = beautify(materializationCode, { indent_size: 2, space_in_empty_paren: true })
        dispatch(Shared.State.UpdateMaterialization(materializationCounter, 'code',
            newCode
            ))
    }
    return <Common.DivWithClassName className='padding5px columnFlexBox flexGrow'>
        <Step.StepField label={"Materialization Template Name"} id={'standard-basic'} nameRef={nameRef} value={name} onFocus={onFocus} onBlur={onBlur} onKeyUp={onKeyUp} onKeyPress={onKeyPress} onChange={onChange}/>
        <Common.DivWithClassName className='columnFlexBox flexStay'>
            <Common.DivWithClassName className='columnFlexBox flexStay'>
                <Common.DivWithClassName className='flexStay width100Percent'>
                    {errorMessage &&
                        <StepMenu.ErrorMessage errorMessageToUse={errorMessage.toString()} />
                    }
                    {!errorMessage && <StepMenu.SuccessMessage successMessage={
                        `Configured handlers ${Object.keys(materializationHandler.handlers)}`
                    } />
                    }
                </Common.DivWithClassName>
            </Common.DivWithClassName>
            <Common.DivWithClassName className='rowFlexBox flexStay'>
                <StepMenu.FormatButton onClick={onFormat} text={'Format JS'} />
            </Common.DivWithClassName>
        </Common.DivWithClassName>
        <Common.DivWithClassName className='flexGrow positionRelative EditorContainer'>
            <ReactResizeDetector handleWidth handleHeight onResize={onResize}>
                <Common.DivWithClassName className='positionAbsolute'>
                    <MonacoEditor
                        width={size.editorWidth}
                        height={size.editorHeight}
                        language="javascript"
                        theme="vs-light"
                        value={materializationCode}
                        options={Common.editorOptions as any}
                        onChange={onChangeCode}
                        editorDidMount={editorDidMount}
                    />
                </Common.DivWithClassName>
            </ReactResizeDetector>
        </Common.DivWithClassName>
    </Common.DivWithClassName>
}