import React, { useEffect, useState, useContext } from 'react';
import { Space, Select, Button, Modal, TreeSelect } from 'antd';

import DatasourceList from './Component/DatasourceList';
import UpdateDatasourceModal from './Component/UpdateDatasourceModal';
import ScheduleCURDModal from './Component/ScheduleCURDModal';
import TaskLogsModal from './Component/TaskLogsModal';
import TaskLogModal from './Component/TaskLogModal';
import UpdateTaskModal from './Component/UpdateTaskModal';
import { dispatch } from '../../../model';
import { showMessage, getQueryParam } from '../../../util';
import { DatasourceContext } from './Component/ContextManager.js';
import { AppContext } from '../../../App';
 
import './index.less';

const { Option } = Select;

const DatasourceManage = (props) => {

  const { env } = useContext(AppContext);

  const domainId = getQueryParam('domainId', props?.location?.search);
  const catalogId = getQueryParam('catalogId', props?.location?.search);
  const scopeId = getQueryParam('scopeId', props?.location?.search);

  const [ treeData, setTreeData ] = useState([]);
  const [ treeValue, setTreeValue ] = useState('');
  const [ treeExpandKeys, setTreeExpandKeys ] = useState([]);
  const [ scopes, setScopes ] = useState([]);
  const [ selectedScope, setSelectedScope] = useState([]);
  const [ rawSupportDatabases, setRawSupportDatabases ] = useState([]);
  const [ supportDatabases, setSupportDatabases ] = useState([]);
  const [ datasources, setDatasources ] = useState([]);
  const [ filterDatasources, setFilterDatasources ] = useState([]);
  const [ selectedDatabaseKey, setSelectedDatabaseKey ] = useState('');
  const [ loadingDatabases, setLoadingDatabases ] = useState(false);
  const [ loadingDatasources, setLoadingDatasources ] = useState(false);
  const [ updateDatasourceModalVisible, setUpdateDatasourceModalVisible ] = useState(false);
  const [ updateDatasourceModalAction, setUpdateDatasourceModalAction ] = useState('');
  const [ scheduleCURDModalVisible, setScheduleCURDModalVisible ] = useState(false);
  const [ updateTaskModalVisible, setUpdateTaskModalVisible ] = useState(false);
  const [ updateTaskModalAction, setUpdateTaskModalAction ] = useState('');
  const [ taskLogsModalVisible, setTaskLogsModalVisible ] = useState(false);
  const [ taskLogModalVisible, setTaskLogModalVisible ] = useState(false);
  const [ currentDatasourceId, setCurrentDatasourceId ] = useState('');
  const [ currentDatasourceIdBindTasksNeedRefresh, setCurrentDatasourceIdBindTasksNeedRefresh ] = useState('');
  const [ currentTaskId, setCurrentTaskId ] = useState('');
  const [ tasksProgress, setTasksProgress ] = useState({});
  const [ currentDatabase,setCurrentDatabase] = useState({})

  const [modal, contextHolder] = Modal.useModal();

  useEffect(() => {
    getScopesAndSupportDatabases();

    const interval = setInterval(() => {
      getAllTasksProgress();
    }, 5000);

    return () => {
      clearInterval(interval);
    }
    //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  useEffect(() => {
    if (env && env.children) {

      env.children.forEach(domain => {
        domain.id = domain.value;
        domain.value = domain.key;

        (domain.children||[]).forEach(system => {
          system.id = system.scopeId;
          system.value = system.key;
        })
      })

      setTreeData(env.children);

      const defaultDomain = (env?.children||[]).length>0 ? env.children[0]: null;

      if (defaultDomain) {
        const defaultSystem = (defaultDomain?.children||[]).length>0 ? defaultDomain.children[0]: null;

        if (defaultSystem) {

          if (domainId!==null && env?.value === Number(domainId)) {
            env.children.forEach(domain => {
              (domain.children||[]).forEach(system => {
                if (system.id === Number(scopeId)) {
                  setTreeValue(system.value);
                }
              })
            })
            
            setSelectedScope([Number(domainId), Number(catalogId), Number(scopeId)]);

          } else {
            setTreeValue(defaultSystem.value);
            setSelectedScope([env?.value, defaultDomain.id, defaultSystem.id]);
          }

          let _expandKeys = [];
          (env.children||[]).forEach(item => {
            _expandKeys.push(item.key);
          })

          setTreeExpandKeys(_expandKeys);

        }
      }
    } else {
      setTreeData([]);
      setTreeValue('');
      setScopes([]);
      setDatasources([]);
      setFilterDatasources([]);
    }
    
    //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [env])

  useEffect(() => {
    if ((selectedScope||[]).length>0) {
      getAllDatasources();
    }
    //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ selectedScope ])

  const getScopesAndSupportDatabases = () => {
    setLoadingDatabases(true);

    dispatch({
      type: 'datasource.getScopesAndSupportedTargetTypes',
      callback: data => {
        setLoadingDatabases(false);
        setScopes(data.scopes||[]);
        setRawSupportDatabases(data.typies||[]);
        setSupportDatabases([{ targetType: 'all', targetName: '全部类型' }, ...(data.typies||[])]);
        setSelectedDatabaseKey('all');
      },
      error: () => {
        setLoadingDatabases(false);
      }
    })
  }

  const getAllDatasources = () => {
    setLoadingDatasources(true);
    dispatch({
      type: 'datasource.getAllDatasources',
      payload: {
        namespace: (selectedScope.length>0?selectedScope[0]:''),
        scope: (selectedScope.length>2?selectedScope[2]:'')
      },
      callback: data => {
        setLoadingDatasources(false);
        setDatasources(data);
        setFilterDatasources((data||[]).filter(item=>selectedDatabaseKey===''||selectedDatabaseKey==='all'||item.type===selectedDatabaseKey));
      },
      error: () => {
        setLoadingDatasources(false);
      }
    })
  }

  const getAllTasksProgress = () => {
    dispatch({
      type: 'datasource.getAllTaskProgress',
      callback: data => {
        setTasksProgress(data||{});
      }
    })
  }

  const onScopeChange = (value) => {

    (treeData||[]).forEach(domain => {
      (domain.children||[]).forEach(system => {
        if (system.value === value) {
          setTreeValue(value);
          setSelectedScope([env?.value, domain.id, system.id]);
        }
      })
    })
  }

  const onDatabaseChange = (value) => {
    setSelectedDatabaseKey(value);
    setFilterDatasources((datasources||[]).filter(item=>value==='all'||item.type===value));
  }

  const showTaskLogs = () => {

    if (loadingDatabases) {
      showMessage('info', '正在获取系统信息,请稍后');
      return;
    }

    if (treeData.length === 0) {
      showMessage('info', '请先创建系统');
      return;
    }

    setTaskLogsModalVisible(true);
  }

  const onTaskLogsModalCancel = () => {
    setTaskLogsModalVisible(false);
  }

  const addDatasource = () => {

    if (loadingDatabases) {
      showMessage('info', '正在获取系统信息,请稍后');
      return;
    }

    if (treeData.length === 0) {
      showMessage('info', '请先创建系统');
      return;
    }

    setUpdateDatasourceModalAction('add');
    setUpdateDatasourceModalVisible(true);
  }

  const editDatasource = (datasource) => {
    setCurrentDatasourceId(datasource.id);
    setUpdateDatasourceModalAction('edit');
    setUpdateDatasourceModalVisible(true);
  }

  const deleteDatasource = (datasource) => {
    modal.confirm({
      title: '是否确认删除该数据源?',
      content: '',
      onOk: () => {
        dispatch({
          type: 'datasource.deleteDatasource',
          payload: {
            datasourceId: datasource.id
          },
          callback: () => {
            showMessage('success', '删除数据源成功');
            getAllDatasources();
          }
        });
      }
    });
  }

  const onScheduleCURDModalCancel = (refresh = false) => {
    setScheduleCURDModalVisible(false);
  }

  const onUpdateDatasourceModalCancel = (refresh = false) => {
    setUpdateDatasourceModalVisible(false);
    refresh && getAllDatasources();
  }

  const addTask = (datasource) => {
    setCurrentDatasourceId(datasource.id||'');
    setUpdateTaskModalAction('add');
    setUpdateTaskModalVisible(true);
    setCurrentDatabase(datasource)
  }

  const scheduleShow = (task) => {
    setCurrentTaskId(task.id);
    setScheduleCURDModalVisible(true);
  }

  const startTask = (task) => {
    modal.confirm({
      title: '是否执行该任务?',
      content: '',
      onOk: () => {
        dispatch({
          type: 'datasource.startTask',
          payload: {
            params: {
              harvestingTaskId: task.id
            }
          },
          callback: () => {
            getAllTasksProgress();
          }
        });
      }
    });
  }

  const editTask = (task) => {
    setCurrentTaskId(task.id);
    setCurrentDatasourceId(task.target.id||'');
    setUpdateTaskModalAction('edit');
    setUpdateTaskModalVisible(true);
  }

  const logTask = (task) => {
    setCurrentTaskId(task.id);
    setTaskLogModalVisible(true);
  }

  const deleteTask = (task) => {
    modal.confirm({
      title: '是否确认删除该任务?',
      content: '',
      onOk: () => {
        dispatch({
          type: 'datasource.deleteTask',
          payload: {
            harvestingTaskId: task.id
          },
          callback: () => {
            setCurrentDatasourceIdBindTasksNeedRefresh(task.target.id||'');
            setCurrentDatasourceId(task.target.id||'');
            showMessage('success', '删除任务成功');
          }
        });
      }
    });
  }

  const onUpdateTaskModalVisibleCancel = (refresh = false) => {
    setUpdateTaskModalVisible(false);
    refresh && setCurrentDatasourceIdBindTasksNeedRefresh(currentDatasourceId);
  }

  const onTaskLogModalCancel = () => {
    setTaskLogModalVisible(false);
  }

  const refreshTasksSuccess = () => {
    setCurrentDatasourceIdBindTasksNeedRefresh('');
  }

  return (
    <DatasourceContext.Provider value={{
      refreshTasksSuccess: refreshTasksSuccess,
      onScheduleShow: scheduleShow,
      onStartTask: startTask,
      onLogTask: logTask,
      onEditTask: editTask,
      onDeleteTask: deleteTask,
      tasksProgress: tasksProgress
    }}>
    <div className='datasource-manage' style={{ backgroundColor: '#fff' }}>
      <div
        className='d-flex p-3'
        style={{
          borderBottom: '1px solid #EFEFEF',
          justifyContent: 'space-between'
        }}
      > 
        <Space>
          <span>系统:</span>
          <TreeSelect 
            style={{width:170}}
            dropdownMatchSelectWidth={210}
            listHeight={450}
            value={treeValue}
            treeData={treeData}
            placeholder="请选择系统"
            treeExpandedKeys={treeExpandKeys}
            onTreeExpand={(keys)=>{
              setTreeExpandKeys(keys);
            }}
            onChange={onScopeChange}
          />
          <span>数据源类型:</span>
          <Select 
            loading={loadingDatabases}
            value={selectedDatabaseKey} 
            style={{ width: 130 }}
            onChange={onDatabaseChange}
          >
          {
            supportDatabases && supportDatabases.map((item, index) => {
              return (
                <Option key={index} value={item.targetType}>{item.targetName}</Option>
              );
            })
          }
          </Select>
        </Space>
        <Space>
          <Button type='primary' onClick={showTaskLogs}>日志报告</Button>
          <Button type='primary' onClick={addDatasource}>新增数据源</Button>
        </Space>
      </div>
      
      <div className='list-container p-3'>
        <DatasourceList 
          loading={loadingDatasources}
          data={filterDatasources||[]}
          scope={selectedScope}
          idBindTasksNeedRefresh={currentDatasourceIdBindTasksNeedRefresh}
          onEdit={editDatasource}
          onAddTask={addTask}
          onDelete={deleteDatasource}
        />
      </div>

      <ScheduleCURDModal 
        visible={scheduleCURDModalVisible}
        id={currentTaskId}
        onCancel={onScheduleCURDModalCancel}
      />

      <TaskLogsModal 
        visible={taskLogsModalVisible}
        scope={selectedScope}
        scopes={scopes}
        onCancel={onTaskLogsModalCancel}
      />

      <UpdateDatasourceModal 
        visible={updateDatasourceModalVisible}
        id={currentDatasourceId}
        scope={selectedScope}
        databases={rawSupportDatabases}
        action={updateDatasourceModalAction}
        onCancel={onUpdateDatasourceModalCancel}
      />

      <UpdateTaskModal
        visible={updateTaskModalVisible}
        id={currentTaskId}
        datasourceId={currentDatasourceId}
        action={updateTaskModalAction}
        currentDatabase={currentDatabase}
        onCancel={onUpdateTaskModalVisibleCancel}
      />

      <TaskLogModal 
        visible={taskLogModalVisible}
        id={currentTaskId}
        onCancel={onTaskLogModalCancel}
      />
      
      {contextHolder}  
    </div>
    </DatasourceContext.Provider>
  );
}

export default DatasourceManage;