import React, { useState, useEffect, useRef } from 'react';
import { Form, Button, Space, Tooltip } from 'antd';
import LocalStorage from 'local-storage';
import { useMount, useUnmount } from 'ahooks';

import ImportAction from './ImportAction';
import CatalogModal from './CatalogModal';
import { dispatchLatest, dispatch } from '../../../../model'; 
import { getQueryParam, showMessage, showNotifaction } from '../../../../util';
import { Action, CatalogId, ModelerId, Hints, ModelerData, PermitCheckOut, Editable, StateId, VersionId, Holder, DDL, RequireId } from '../../../../util/constant';
import HistoryAndVersionDrawer from './HistoryAndVersionDrawer';

import './EditModel.less';

const EditModel = (props) => {

  const [ actionData, setActionData ] = useState({ action: '', catalogId: '', modelerId: '', hints: [],  roughModelerData: null, permitCheckOut: false, editable: false, stateId: '', versionId: '', ddl: '', requireId: '' });

  const [ modelerData, setModelerData ] = useState({});
  const [ terms, setTerms ] = useState([]);
  const [ confirmLoading, setConfirmLoading ] = useState(false);
  const [ catalogModalVisible, setCatalogModalVisible ] = useState(false);
  const [ historyAndVersionDrawerVisible, setHistoryAndVersionDrawerVisible ] = useState(false);
  const [ autoTabKey, setAutoTabKey ] = useState(null);

  const actionRef = useRef('');

  const { action, catalogId, modelerId, hints, roughModelerData, permitCheckOut, editable, stateId, versionId, holder, ddl, requireId } = actionData;

  const [form] = Form.useForm();

  useEffect(() => {
    const _action = getQueryParam(Action, props.location.search);
    const _catalogId = getQueryParam(CatalogId, props.location.search);
    const _modelerId = getQueryParam(ModelerId, props.location.search);
    const _hintsStr = getQueryParam(Hints, props.location.search);
    const _modelerDataStr = getQueryParam(ModelerData, props.location.search)
    const _permitCheckOut = getQueryParam(PermitCheckOut, props.location.search);
    const _editable = getQueryParam(Editable, props.location.search);
    const _stateId = getQueryParam(StateId, props.location.search);
    const _versionId = getQueryParam(VersionId, props.location.search);
    const _holder = getQueryParam(Holder, props.location.search);
    const _ddl = getQueryParam(DDL, props.location.search);
    const _requireId = getQueryParam(RequireId, props.location.search);


    let _hints = [];
    if ((_hintsStr||'') !== '') {
      _hints = _hintsStr.split(',');
    }

    let _roughModelerData = null;
    if ((_modelerDataStr||'') !== '') {
      _roughModelerData = JSON.parse(_modelerDataStr);

      judgeAttributeRepeat(_roughModelerData.easyDataModelerDataModelAttributes);
    } 

    setActionData({ action: _action, catalogId: _catalogId, modelerId: _modelerId, hints: _hints, roughModelerData: _roughModelerData, permitCheckOut: (_permitCheckOut==='true'), editable: (_editable==='true'), stateId: _stateId, versionId: _versionId, holder: _holder, ddl: _ddl, requireId: _requireId });
    actionRef.current = _action;

    const interval = setInterval(() => {
      heartbeat();
    }, 10*60*1000);

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

  useMount(() => {
    window?.addEventListener('beforeunload', confirmQuit);
  })

  useUnmount(() => {
    window?.removeEventListener('beforeunload', confirmQuit);
  })

  const heartbeat = () => {
    dispatchLatest({
      type: 'datamodel.heartbeat'
    });
  }

  const confirmQuit = (e) => {
    if (actionRef.current === 'edit') {
      e.returnValue = '';
    }
  }

  const judgeAttributeRepeat = (attrs) => {
    const names = [], nameCountMap = {}, terms = [];

    var repeat = false;
    (attrs||[]).forEach(item => {
      names.push(item.name||'');

      if (nameCountMap[item.name]) {
        nameCountMap[item.name]++;
      } else {
        nameCountMap[item.name] = 1;
      }
    })

    Object.keys(nameCountMap).forEach(key => {
      if (nameCountMap[key] > 1) {
        repeat = true;
        terms.push(key);
      }
    })

    if (repeat) {
      setAutoTabKey('2');
      setTerms(terms);
    }
  }

  const save = async (e, cid = '') => {

    setAutoTabKey(null);

    try {
      const row = await form.validateFields();

      const newModelerData = {...modelerData, ...row};

      if (newModelerData.easyDataModelerModelingTemplate==='' || newModelerData.easyDataModelerModelingTemplate==={}) {
        newModelerData.easyDataModelerModelingTemplate = null;
      } 

      if (newModelerData.partition && ( !newModelerData.partition.partitionType || newModelerData.partition.partitionType==={} || (newModelerData.partition.keys||[]).length===0 )) {
        newModelerData.partition = null;
      }

      if (action==='add' && (cid||'')==='' && ((catalogId||'')==='')) {
        setCatalogModalVisible(true);
        return ;
      }

      setConfirmLoading(true);
      dispatchLatest({
        type: 'datamodel.saveDataModel',
        payload: { 
          data: newModelerData
        },
        callback: data => {
          if (action === 'add') {
            dispatchLatest({
              type: 'datamodel.bindCatalogDataModel',
              payload: { 
                params: {
                  easyDataModelCatalogId: ((cid||'')!=='')?cid:catalogId,
                  easyDataModelerDataModelIds: data.id||''
                }
              },
              callback: message => {
                setConfirmLoading(false);
                setTerms([]);

                if ((message||'')!=='' && (message||'')!=='ok') {
                  showNotifaction('提示', message, 5);
                } else {
                  showMessage("success", '新增模型成功');
                }

                setActionData({ ...actionData, ...{ action: 'detail', modelerId: data.id||'', editable: data?.editable||false, stateId: data?.state?.id||'' } });
                actionRef.current = 'detail';

                LocalStorage.set('modelChange', !(LocalStorage.get('modelChange')||false));

                if (requireId) {
                  dispatch({
                    type: 'datamodel.requirementBind',
                    payload: {
                      data: {
                        techJobId: parseInt(requireId),
                        assocStringIdList: [data.id]
                      }
                    },
                    callback: () => {
                      LocalStorage.set('modelChange', !(LocalStorage.get('modelChange')||false));
                    }
                  });
                } 
              },
              error: () => {
                setConfirmLoading(false);
              }
            })
          } else {
            setConfirmLoading(false);
            setTerms([]);

            showMessage("success", '保存模型成功');

            const _action = getQueryParam(Action, props.location.search);
            
            setActionData({ ...actionData, ...{ action: (_action==='flow')?'flow':'detail', modelerId: data.id||'', stateId: data?.state?.id||'', permitCheckOut: data?.permitCheckOut||false, editable: data?.editable||false } });
            actionRef.current = (_action==='flow')?'flow':'detail';

            LocalStorage.set('modelChange', !(LocalStorage.get('modelChange')||false));
          }
        },
        error: (err) => {
          setConfirmLoading(false);
          setTerms([err.ApiError?.message||'']);
        }
      })

    } catch (errInfo) {
      console.log('Validate Failed:', errInfo);
      setAutoTabKey('1');
    }

  }

  const edit = () => {
    setActionData({ ...actionData, action: 'edit' });
    actionRef.current = 'edit';
  }

  const cancelEdit = () => {
    const _action = getQueryParam(Action, props.location.search);

    setActionData({ ...actionData, action: (_action==='flow')?'flow':'detail' });
    actionRef.current = (_action==='flow')?'flow':'detail';
  }

  const onActionChange = (data) => {
    setModelerData(data);

    const _action = getQueryParam(Action, props.location.search);
    if (_action === 'flow' || (permitCheckOut&&data?.permitCheckOut===false)) {
      setActionData({ ...actionData, ...{modelerId: data?.id, editable: data?.editable||false, stateId: data?.state?.id||'', permitCheckOut: data?.permitCheckOut||false}  });
    }
  }

  const onCatalogModalCancel = (id = null) => {
    setCatalogModalVisible(false);

    if ((id||'') !== '') {
      save(null, id);
    }
  }

  const onHistory = () => {
    setHistoryAndVersionDrawerVisible(true);
  }

  const onHistoryAndVersionDrawerCancel = () => {
    setHistoryAndVersionDrawerVisible(false);
  }

  let title = '';
  if (action === 'add') {
    title = '新增模型';
  } else if (action === 'edit') {
    title = '模型编辑';
  } else if (action === 'detail' || action === 'flow') {
    title = '模型详情';
  } else if (action === 'detail-version') {
    title = '模型版本详情';
  }

  let actionsBtn = null;

  if (action==='add') {
    actionsBtn = (
      <Space>
        <Button 
          type='primary' 
          onClick={save}
          loading={confirmLoading}
          danger
        >
        保存
        </Button>
      </Space>
    )
  } else if (action === 'detail') {

    let editTip = '';
    if (!editable && stateId !== '4') {
      if (stateId === '2') {
        editTip = '待发布的模型不允许编辑';
      }
    }

    if (!permitCheckOut && stateId === '4') {
      editTip = `${holder||''}正在编辑中, 不允许再编辑`;
    }

    actionsBtn = (
      <Space>
        <Button type='primary' onClick={onHistory} danger >版本历史</Button>
        <Tooltip title={editTip}>
          <Button type='primary' onClick={edit} disabled={(stateId==='4')?!permitCheckOut:!editable} danger >
            编辑
          </Button>
        </Tooltip>
      </Space>
    );
  } else if (action === 'edit') {
    actionsBtn = (
      <Space>
        <Button onClick={cancelEdit} >
        取消
        </Button>
        <Button type='primary' onClick={onHistory} danger >
          版本历史
        </Button>
        <Button 
          type='primary' 
          onClick={save}
          loading={confirmLoading}
          danger
        >
        保存
        </Button>
      </Space>
    )
  } else if (action === 'flow') {
    actionsBtn = (
      <Space>
        <Button type='primary' onClick={onHistory} danger>
        版本历史
        </Button>
        {
          editable && <Button type='primary' onClick={edit} danger >
          编辑
          </Button>
        }
      </Space>
    );
  }

  return (
    <div className='edit-model position-relative'>
      <div className='edit-header'>
        <span style={{ fontSize: 16, fontWeight: 'bold', color: '#fff' }}>{title}</span>
      </div>
      <div className='edit-container'>
        <div className='edit-container-card'>
          <ImportAction hints={hints} onChange={onActionChange} action={action} modelerId={modelerId} ddl={ddl} form={form} terms={terms} roughModelerData={roughModelerData} permitCheckOut={permitCheckOut} stateId={stateId} versionId={versionId} autoTabKey={autoTabKey} {...props} /> 
        </div>
      </div>
      <div className='edit-footer'>
      {actionsBtn}  
      </div>
      <CatalogModal
        visible={catalogModalVisible}
        onCancel={onCatalogModalCancel}
      />
      <HistoryAndVersionDrawer
        id={modelerId}
        visible={historyAndVersionDrawerVisible}
        onCancel={onHistoryAndVersionDrawerCancel}
      />
    </div>
  );
} 

export default EditModel;