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 Immer from 'immer'
import * as Drag from './Drag'
import * as Common from './common'
import * as Task from './Task'
import * as CreateTask from './CreateTask'
import useResizeAware from 'react-resize-aware';
import * as Steps from './Steps2'
import './Settings.scss';

import * as Shared from 'placeholder-shared'
import * as Antd from 'antd'
import { DownOutlined } from '@ant-design/icons';

const layout = {
  labelCol: { span: 5 },
  wrapperCol: { span: 16 },
};
const tailLayout = {
  wrapperCol: { offset: 5, span: 16 },
};

export const Scheduling = (props) => {
    const dispatch = useDispatch()
    const currentTask = useSelector(state=>(state as any).currentTask)
    const currentTaskData = useSelector(state => (state as any).tasks[currentTask])
    const getMenu = ()=> {
        return <Antd.Menu>
            {/*
        <Antd.Menu.Item>
          <a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">
            Hourly
          </a>
        </Antd.Menu.Item>
            */}
            <Antd.Menu.Item onClick={
                (e) => {
                    dispatch(Shared.State.getUpdateTaskAction(currentTask, 'schedule',
                        'none'))
                }
            }>
                <a>
                    None
          </a>
            </Antd.Menu.Item>
            <Antd.Menu.Item onClick={
                (e) => {
                    dispatch(Shared.State.getUpdateTaskAction(currentTask, 'schedule',
                        'daily'))
                }
            }
            >
                <a>
                    Daily
          </a>
            </Antd.Menu.Item>
            {/*}
        <Antd.Menu.Item>
          <a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">
            Weekly
          </a>
        </Antd.Menu.Item>
        */}
        </Antd.Menu>
    } 
    return <Common.DivWithClassName className='paddingTop5px columnFlexBox flexGrow'>
      <Common.DivWithClassName className='paddingTop5px columnFlexBox flexGrow'>
        <Antd.Dropdown overlay={getMenu()}>
            <a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
                {currentTaskData.schedule && currentTaskData.schedule.charAt(0).toUpperCase() + currentTaskData.schedule.slice(1)}<DownOutlined />
            </a>
        </Antd.Dropdown>
        </Common.DivWithClassName>
    </Common.DivWithClassName>
}
export const Settings = (props:{}) => {
  const UIState = useSelector(state=> (state as any).UIState)
  const activeKey = (UIState.settingsTabKey) ? UIState.settingsTabKey : "Snowflake";
  const dispatch = useDispatch();
  const setActiveKey = (key)=>{
    dispatch(Shared.State.changeUIState('settingsTabKey', key));
  }
  return (
    /*<Common.DivWithClassName className='backgroundWhite positionRelative width100Percent height100Percent'>
      <Common.DivWithClassName className='positionAbsolute overflowYScroll width100Percent height100Percent'>
        <Common.DivWithClassName className='padding20px height100Percent flexGrow columnFlexBox antdTabsContainer'>*/
          <Antd.Tabs className='horizontalPadding20' activeKey={activeKey} tabPosition="top" onChange={setActiveKey}>
            <Antd.Tabs.TabPane tab="Snowflake" key="Snowflake" className='flexGrow'>
              <SnowflakeSettings />
      </Antd.Tabs.TabPane>
      <Antd.Tabs.TabPane tab="GitHub" key="GitHub" className='flexGrow'>
        <GitHubSettings />
      </Antd.Tabs.TabPane>
      <Antd.Tabs.TabPane tab="Scheduler" key="Scheduler" className='flexGrow'>
        <Scheduling />
            </Antd.Tabs.TabPane>
          </Antd.Tabs>/*
        </Common.DivWithClassName>
      </Common.DivWithClassName>
    </Common.DivWithClassName>*/
  );
}


export const useChangeUserConfig = (key) => {
    const dispatch = useDispatch()
    return useCallback((e) => {
        dispatch(Shared.State.getUpdateConfigAction(key,e.target.value))
    },[key,dispatch])
}

export const SnowflakeSettings = (props:{}) => {
  const SettingsState  = {
    initial : 1, 
    loading : 2,
    success : 3,
    fail: 4
  }
  interface ISettingsState {
    settingsState?: number;
    successString?: string;
    errorString?: string;
    accountInput?: string;
    usernameInput?: string;
    passwordInput?: string;
    roleInput?: string;
    warehouseInput?: string;
    destinationDBInput?: string;
    destinationSchemaInput?: string;
  }
  const [settingsInfo, setSettingsInfo] = useState<ISettingsState>({
    settingsState: SettingsState.initial,
    successString: '',
    errorString: ''
  });

    const changeAccount = useChangeUserConfig('snowflakeAccount')
    const changeUsername = useChangeUserConfig('snowflakeUsername')
    const changePassword = useChangeUserConfig('snowflakePassword')
    const changeRole = useChangeUserConfig('snowflakeRole')
    const changeWarehouse = useChangeUserConfig('snowflakeWarehouse')
    const userConfig:Shared.State.IUserConfig = useSelector(state=> (state as any).userConfig)

  
    const onFinish = (values)=> {
        console.log("FINISEHD!: ", values);

    }
    const onTestConnection = (e) => {
      setSettingsInfo({
        settingsState: SettingsState.loading
      })
      var test = Shared.Snowflake.runListTables(userConfig)
      .then((tablelist)=>{
        setSettingsInfo({
          settingsState: SettingsState.success,
          successString: "Successfully Connected to Snowflake"
        })
      })
      .catch((err)=>{
        let msg;
        msg = JSON.stringify(err);
        setSettingsInfo({
          settingsState: SettingsState.fail,
          errorString: msg
        });
      })
      .finally(()=>{
        console.log('TEST RUN COMPLETE!')
      })
    }
    const { settingsState, successString, errorString } = settingsInfo
    const dispatch = useDispatch()
    const currentTask = useSelector(state => (state as any).currentTask)
    const currentTaskData = useSelector(state => (state as any).tasks[currentTask])
    const hasShownModal = useSelector(state => (state as any).hasShownModal);
   
    const onChange = (e:any) => {
        dispatch(Shared.State.getUpdateTaskAction(currentTask, 'destinationSchema', e.target.value))
    }

    const onChangeDatabase = (e:any) => {
        dispatch(Shared.State.getUpdateTaskAction(currentTask, 'destinationDatabase', e.target.value))
    }
    return <Antd.Form
      {...layout}
      size='small'
      name="basic"
      initialValues={Object.assign({}, userConfig, currentTaskData)}
      onFinish={onFinish}
      //onFinishFailed={onFinishFailed}
      className="settingsContainer" 
    >
      <Antd.Form.Item className="marginBottom-5" {...tailLayout} name="title">
        <Antd.Typography.Title level={4}>Snowflake Settings</Antd.Typography.Title>
			</Antd.Form.Item>
      
      <Antd.Form.Item {...tailLayout}>
        <span>Not ready to enter your snowflake settings? <br />
        Try the 
        <a href="https://editor.structure.rest/app/editor?env=demo" target="_blank">
          &nbsp;demo environment&nbsp;</a>or join us in&nbsp;<a href="https://join.slack.com/t/structuresupport/shared_invite/zt-ddx04ho4-_q43i5o3zQ9jv00qx~dx8A" target="_blank"> 
          slack.</a>
          </span>
    </Antd.Form.Item>

      <Antd.Form.Item
        label="Account"
        name="snowflakeAccount"
        extra={<span>http://&lt;<span className='accentColor'>Your account name is here</span>&gt;.snowflakecomputing.com</span>}
        rules={[{ required: true, message: 'Enter your Snowflake Account!' }]}
      >
        <Antd.Input onChange={changeAccount} value={userConfig.snowflakeAccount} />
      </Antd.Form.Item>
      <Antd.Form.Item
        label="Username"
        name="snowflakeUsername"
        rules={[{ required: true, message: 'Enter your Snowflake username!' }]}
      >
        <Antd.Input onChange={changeUsername} value={userConfig.snowflakeUsername}/>
      </Antd.Form.Item>

      <Antd.Form.Item
        label="Password"
        name="snowflakePassword"
        rules={[{ required: true, message: 'Please input your Snowflake password!' }]}
      >
        <Antd.Input.Password onChange={changePassword} value={userConfig.snowflakePassword}/>
      </Antd.Form.Item>
      <Antd.Form.Item
        label="Role (Optional)"
        name="snowflakeRole"
        rules={[{ required: false, message: 'Please input your Snowflake role!' }]}
      >
        <Antd.Input onChange={changeRole} value={userConfig.snowflakeRole}/>
      </Antd.Form.Item>
      <Antd.Form.Item
        label="Warehouse (Optional)"
        name="snowflakeWarehouse"
        rules={[{ required: false, message: 'Please input your Snowflake warehouse!' }]}
      >
        <Antd.Input onChange={changeWarehouse} value={userConfig.snowflakeWarehouse}/>
      </Antd.Form.Item>

      {/*START SCHEMA STUFF HERE*/}
      <Antd.Form.Item className="marginBottom-5" {...tailLayout}>
      
        <Antd.Typography.Title level={4}>Schema Settings</Antd.Typography.Title>
			</Antd.Form.Item>
      <Antd.Form.Item
        label="Destination Database"
        name="destinationDatabase"
        extra="You must create a database in Snowflake first, and then add the name of that DB here."
        rules={[{ required: true }]}
      >
               <Antd.Input value={currentTaskData.destinationDatabase} onChange={onChangeDatabase} placeholder='Database' />
      </Antd.Form.Item>
      <Antd.Form.Item
      label='Destination Schema'
      name='destinationSchema'
      rules={[{required:true}]}
      >
        <Antd.Input value={currentTaskData.destinationSchema} onChange={onChange} placeholder='Destination Schema' />
      </Antd.Form.Item>
      {/*END SCHEMA STUFF HERE*/}
      <Antd.Form.Item {...tailLayout}>
            {settingsState == SettingsState.initial &&
              <Antd.Space direction="vertical" > 
                <Antd.Button onClick={onTestConnection} type="dashed" htmlType="submit">
                  Test Connection
                </Antd.Button>
                <Antd.Alert className="visibilityHidden" type="info" message="Results will display here." />
              </Antd.Space>
            }
            {settingsState == SettingsState.loading  &&
              <Antd.Space direction="vertical">
                <Antd.Button onClick={(e)=>{alert('waiting for now')}} type="dashed" htmlType="submit" loading>
                  Test Connection
                </Antd.Button>
                <Antd.Alert type="warning" message="Loading..." />
              </Antd.Space>
            }
            {settingsState == SettingsState.success  &&
               <Antd.Space direction="vertical">
                <Antd.Button onClick={onTestConnection} type="dashed" htmlType="submit">
                  Test Connection
                </Antd.Button>
                <Antd.Alert type="success" message={successString} />
              </Antd.Space>
            }
            {settingsState == SettingsState.fail  &&
               <Antd.Space direction="vertical">
                <Antd.Button onClick={onTestConnection} type="dashed" htmlType="submit">
                  Test Connection
                </Antd.Button>
                <Antd.Alert type="error" message={errorString} />
                </Antd.Space>
            }       
      </Antd.Form.Item>
    </Antd.Form>
}


export const GitHubSettings = (props:{}) => {
  const SettingsState  = {
    initial : 1, 
    loading : 2,
    success : 3,
    fail: 4
  }
  interface ISettingsState {
    settingsState?: number;
    successString?: string;
    errorString?: string;
    usernameInput?: string;
    tokenInput?: string;
    repoInput?: string;
    shaInput?: string;
  }
  const [settingsInfo, setSettingsInfo] = useState<ISettingsState>({
    settingsState: SettingsState.initial,
    successString: '',
    errorString: ''
  });

    const changeGitUsername = useChangeUserConfig('gitUsername')
    const changeGitToken = useChangeUserConfig('gitToken')
    const changeGitRepo = useChangeUserConfig('gitRepoName')
    
    const userConfig = useSelector(state=> (state as any).userConfig)
    const UIState = useSelector(state=> (state as any).UIState);
    const versionControlState = useSelector(state=> (state as any).versionControlState)
    const dispatch = useDispatch();
    const onFinish = (values)=> {
        console.log("FINISEHD!: ", values);

    }
    const onTestConnection = (e) => {
      setSettingsInfo({
        settingsState: SettingsState.loading
      })
      Shared.GitHub.getRepo(userConfig.gitToken, userConfig.gitUsername, userConfig.gitRepoName)
      .then((data:any)=>{
        dispatch(Shared.VersionControlActions.dummyFnThunk()) //changes MenuStatus back to awaitingGitCmd
        setSettingsInfo({
          settingsState: (data.responseMessage.type == Shared.GitHub.MessageType.success) ? SettingsState.success : SettingsState.fail,
          successString: data.responseMessage.text,
          errorString: data.responseMessage.text,
        })
      })
      .catch((err)=>{
        setSettingsInfo({
          settingsState: SettingsState.fail,
          errorString: (err instanceof Error) ? err.toString() : JSON.stringify(err)
        });
      })
      .finally(()=>{
        console.log('TEST RUN COMPLETE!')
      })
    }
    const { settingsState, successString, errorString } = settingsInfo
    

    const startGitHubClickThrough = (e) =>{
      dispatch(Shared.VersionControlActions.createGitRepoThunk())
    }
    const resetGitRepo = (e) =>{
      dispatch(Shared.VersionControlActions.setGitRepoThunk())
    }
    const [form] = Antd.Form.useForm();
    useEffect(()=>{
      form.resetFields()
    }, [versionControlState])
    

    
    return <Antd.Form
      {...layout}
      form={form}
      size='small'
      name="basic"
      initialValues={userConfig}
      onFinish={onFinish}
      //onFinishFailed={onFinishFailed}
      className="settingsContainer" 
    >
      <Antd.Form.Item className="marginBottom-5" {...tailLayout} name="title">
        <Antd.Typography.Title level={4}>GitHub Settings</Antd.Typography.Title>
			</Antd.Form.Item>
    
      <Antd.Form.Item label="Username">
        <Antd.Form.Item
          name="gitUsername"
          noStyle
          rules={[{ required: true, message: 'GitHub Username is required' }]}
        >
          <Antd.Input style={{ width: 400 }} onChange={changeGitUsername} value={userConfig.gitUsername} />
        </Antd.Form.Item>
        
      </Antd.Form.Item>

      <Antd.Form.Item
        label="Token"
        name="gitToken"
        rules={[{ required: true, message: 'Enter your Access Token!' }]}
      >
        <Antd.Input.Password style={{ width: 400 }} onChange={changeGitToken} value={userConfig.gitToken} />
      </Antd.Form.Item>
      <Antd.Form.Item style={{marginTop:'-20px'}} {...tailLayout}>
          <span>The Access Token should be scoped for Full Repo Access <br /> to ensure complete functionality.</span>
          <a href="https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token">&nbsp;&nbsp;Learn more...</a>
      </Antd.Form.Item>
      {userConfig.gitRepoName &&
      
        <Antd.Form.Item
          label="Repo"
          extra={<>Your repo contains a yaml file of your pipeline. <Antd.Button type="link" onClick={resetGitRepo}>Unlink Repo</Antd.Button></>}
          name="gitRepoName"
          //rules={[{ required: true, message: 'Please input your Github Repo Name' }]}
        >
          <Antd.Input disabled={true} onChange={changeGitRepo} value={userConfig.gitRepoName}/>
        </Antd.Form.Item>
      }
      {!userConfig.gitRepoName &&
        <Antd.Form.Item label="Repo">
          <Antd.Tooltip title="Click Through to Configure GitHub">
            <Antd.Button type="link" onClick={startGitHubClickThrough}>First Time Repo Setup...</Antd.Button>
          </Antd.Tooltip>
        </Antd.Form.Item>
      }
      <Antd.Form.Item {...tailLayout}>
            {settingsState == SettingsState.initial &&
              <Antd.Space direction="vertical" > 
                <Antd.Button onClick={onTestConnection} type="dashed" htmlType="submit">
                  Test Connection
                </Antd.Button>
                <Antd.Alert className="visibilityHidden" type="info" message="Results will display here." />
              </Antd.Space>
            }
            {settingsState == SettingsState.loading  &&
              <Antd.Space direction="vertical">
                <Antd.Button onClick={(e)=>{alert('waiting for now')}} type="dashed" htmlType="submit" loading>
                  Test Connection
                </Antd.Button>
                <Antd.Alert type="warning" message="Loading..." />
              </Antd.Space>
            }
            {settingsState == SettingsState.success  &&
               <Antd.Space direction="vertical">
                <Antd.Button onClick={onTestConnection} type="dashed" htmlType="submit">
                  Test Connection
                </Antd.Button>
                <Antd.Alert type="success" message={successString} />
              </Antd.Space>
            }
            {settingsState == SettingsState.fail  &&
               <Antd.Space direction="vertical">
                <Antd.Button onClick={onTestConnection} type="dashed" htmlType="submit">
                  Test Connection
                </Antd.Button>
                <Antd.Alert type="error" message={errorString} />
                </Antd.Space>
            }
      </Antd.Form.Item>
    </Antd.Form>
}
