import React from 'react';
import { Button, Space, Spin, Input, Select, Tooltip, Radio, Modal } from 'antd';
import copy from "copy-to-clipboard";  
import { CaretLeftOutlined, CaretRightOutlined } from '@ant-design/icons';
import classNames from 'classnames';

import ModelTree from './Component/ModelTree';
import ModelTable from './Component/ModelTable';
import ImportModal from './Component/ImportModal';
import ImportStockWordDrawer from './Component/ImportStockWordDrawer';
import ExportDDLModal from './Component/export-ddl';
import ExportOtherModal from './Component/ExportOtherModal';
import RecatalogModal from './Component/RecatalogModal';
import HistoryAndVersionDrawer from './Component/HistoryAndVersionDrawer';
import StartFlowModal from './Component/StartFlowModal';
import { showMessage, showNotifaction, inputWidth, DeleteTipModal, getDataModelerRole } from '../../../util';
import { dispatch, dispatchLatestHomepage } from '../../../model'; 
import { Action, CatalogId, ModelerId, Hints, ModelerData, PermitCheckOut, Editable, StateId, Holder, DDL, RequireId, DataModelerRoleReader } from '../../../util/constant';
import { AppContext } from '../../../App';
import DebounceInput from './Component/DebounceInput';
import MetadataAnalysis from '../../QianKun/MetadataAnalysis';
import BatchModeler from './Component/BatchModeler';
import IframeDrawer from '../ModelConfig/Component/IframeDrawer'

import './index.less';

const { Option } = Select;

const InputDebounce = DebounceInput(300)(Input);

class ModelComponet extends React.Component {

  constructor() {
    super();
    this.state = {
      importModalVisible: false,
      importStockWordDrawerVisible: false,
      exportDDLModalVisible: false,
      exportOtherModalVisible: false,
      recatalogModalVisible: false,
      historyAndVersionDrawerVisible: false,
      startFlowModalVisible: false,
      catalogId: '',
      importModalAction: '',
      tableData: [],
      filterTableData: [],
      loadingTableData: false, 
      selectModelerIds: [],
      selectModelerNames: [],
      keyword: '',
      hints: [],
      loadingStates: false,
      modelStates: [],
      currentModelState: '',
      currentView: '',
      exportDDLModalReference: 'exportDDL',
      currentModel: {},
      offset: null,
      expandTree: true,
      showUnbindTip: false,
      showMode: 'list',
      showBatchModeler: false,
      iframeDrawerParams: {
        visible: false,
        title: undefined,
        url: undefined,
      }
    }
  }
  
  componentDidMount() {
    this.getModelStates();

    window?.addEventListener("storage", this.modelEventChange);
  }

  componentWillUnmount() {
    window?.removeEventListener("storage", this.modelEventChange);
  }

  modelEventChange = (e) => {
    if (e.key === 'modelChange') {
      this.onTableChange();
    }
  }

  getModelStates = () => {
    this.setState({ loadingStates: true }, () => {
      dispatch({
        type: 'datamodel.loadDataModelStateCatalog',
        callback: data => {
          this.setState({
            loadingStates: false,
            modelStates: [{ name: 'all', id: '', cnName: '所有状态' }, ...(data?.subCatalogs||[])]
          });
        },
        error: () => {
          this.setState({ loadingStates: false });
        }
      });
    })
  }

  onViewChange = (value) => {
    this.setState({ currentView: value });
  }

  onModelStateChange = (value) => {
    this.setState({ currentModelState: value, offset: null }, () => {
      this.onTableChange();
    })
  }

  onTreeSelect = (key, offset=null) => {

    this.setState({ catalogId: key, keyword: '', offset, currentModelState: (offset!==null)?'':this.state.currentModelState }, () => {
      if (!key || key==='') {
        this.setState({ tableData: [], filterTableData: [] });
      } else {
        this.onTableChange();
      }
    });
  }

  onTableChange = () => {
    const { currentView, catalogId, keyword, currentModelState } = this.state;

    this.setState({ loadingTableData: true }, () => {
      if (keyword === '') {
        if (currentView === 'dir') {

          const params = {
            easyDataModelerCatalogId: catalogId,
          };

          if (currentModelState !== '') {
            params.stateId = currentModelState;
          }

          dispatchLatestHomepage({
            type: 'datamodel.getCurrentDataModelCatalog',
            payload: params,
            callback: data => {
              this.setState({ loadingTableData: false, tableData: data.easyDataModelerDataModels||[], filterTableData: data.easyDataModelerDataModels||[] });
            },
            error: () => {
              this.setState({ loadingTableData: false });
            }
          })
        } else if (currentView === 'state') {
          dispatchLatestHomepage({
            type: 'datamodel.getCurrentDataModelStateCatalog',
            payload: {
              easyDataModelerStateCatalogId: catalogId
            },
            callback: data => {
              this.setState({ loadingTableData: false, tableData: data.easyDataModelerDataModels||[], filterTableData: data.easyDataModelerDataModels||[] });
            },
            error: () => {
              this.setState({ loadingTableData: false });
            }
          })
        } else {
          dispatchLatestHomepage({
            type: 'datamodel.getBindingDataList',
            payload: {
              techJobId: catalogId
            },
            callback: data => {
              this.setState({ loadingTableData: false, tableData: data||[], filterTableData: data||[] });
            },
            error: () => {
              this.setState({ loadingTableData: false });
            }
          })
        }
      } else {

        const params = {
          term: keyword,
        };

        if (currentModelState !== '') {
          params.stateId = currentModelState;
        }

        dispatchLatestHomepage({
          type: 'datamodel.searchModel',
          payload: params,
          callback: data => {
            this.setState({ loadingTableData: false, tableData: data||[], filterTableData: data||[] });
          },
          error: () => {
            this.setState({ loadingTableData: false });
          }
        })
      }
      
    })
  }

  onTableSelect = (ids) => {
    this.setState({ selectModelerIds: ids });
  }

  onTableItemAction = (record, action) => {
    this.setState({ importModalAction: action, modelerId: record.id }, () => {
      const { catalogId, importModalAction, modelerId } = this.state;
      this.setState({
        iframeDrawerParams: {
          visible: true,
          title: (importModalAction==='detail')?'模型详情':'模型编辑',
          url: `/data-govern/data-model-action?${Action}=${importModalAction}&${CatalogId}=${catalogId}&${ModelerId}=${modelerId}&${PermitCheckOut}=${record.permitCheckOut||false}&${Editable}=${record.editable||false}&${StateId}=${record.state?.id||''}&${Holder}=${record.holder||''}`
        }
      })
    });
  }

  onHistory = (id) => {
    this.setState({ historyAndVersionDrawerVisible: true, modelerId: id });
  }

  onSearchInputChange = (value) => {
    this.setState({ keyword: value||'', catalogId: '' }, () => {
      if (value !== '') {
        this.onTableChange();
      }
    });
  }

  onImportUnconditionBtnClick = () => {
    const { catalogId, currentView } = this.state;

    this.setState({
      iframeDrawerParams: {
        visible: true,
        title: '新增模型',
        url: `/data-govern/data-model-action?${Action}=add&${CatalogId}=${(currentView==='dir')?(catalogId||''):''}`
      }
    })
  }

  onExportDDLBtnClick = () => {
    const { selectModelerIds, tableData } = this.state;
    if ((selectModelerIds||[]).length === 0) {
      showMessage('info', '请先选择模型');
      return;
    }

    this.setState({ exportDDLModalVisible: true });
  }

  onExportOtherBtnClick = () => {
    this.setState({ exportOtherModalVisible: true });
  }

  startFlow = () => {
    const { selectModelerIds } = this.state;
    if ((selectModelerIds||[]).length === 0) {
      showMessage('info', '请先选择模型');
      return;
    }

    this.setState({ startFlowModalVisible: true });
  }

  onRecatalogBtnClick = () => {
    const { selectModelerIds } = this.state;
    if ((selectModelerIds||[]).length === 0) {
      showMessage('info', '请先选择模型');
      return;
    }

    this.setState({ recatalogModalVisible: true });
  }

  onBatchDeleteBtnClick = () => {

    const { selectModelerIds } = this.state;
    if ((selectModelerIds||[]).length === 0) {
      showMessage('info', '请先选择模型');
      return;
    }

    this.props.modal?.confirm({
      title: '提示',
      content: '是否确认删除选中内容',
      onOk: () => {
        dispatch({
          type: 'datamodel.deleteDataModels',
          payload: {
            params: {
              easyDataModelerDataModelIds: selectModelerIds.join(',')
            }
          },
          callback: (tip) => {
            this.onTableChange();
            this.setState({ selectModelerIds: [] });
            if (tip) {
              if (tip === '删除成功') {
                showMessage('success', '删除成功')
              } else {
                showMessage('warn', '存在非草稿态模型无法删除')
              }
            }
          }
        })
      }
    });
  }

  onBatchModelerBtnClick = () => {
    this.setState({ showBatchModeler: true });
  }

  onBatchUnbindBtnClick = () => {
    const { selectModelerIds } = this.state;
    if ((selectModelerIds||[]).length === 0) {
      showMessage('info', '请先选择模型');
      return;
    }

    this.setState({ showUnbindTip: true });
  }

  onAutoCreateTable = (item) => {

    this.setState({ exportDDLModalVisible: true, selectModelerNames: [item.name||''], exportDDLModalReference: 'createTable', currentModel: item });
  }

  onImportExcelVisibleChange = (visible = false, hint = null) => {
    this.setState({ importExcelVisible: visible });
  }

  onImportModalCancel = (refresh = false, confirm = false, hints = []) => {
    const { catalogId, currentView } = this.state;

    this.setState({ importModalVisible: false }, () => {
      refresh && this.onTableChange();

      if (confirm) {
        if ((hints||[]).length > 0) {
          if (currentView === 'requirement') {
            setTimeout(() => {
              this.setState({
                iframeDrawerParams: {
                  visible: true,
                  title: '新增模型',
                  url: `/data-govern/data-model-action?${Action}=add&${RequireId}=${catalogId||''}&${Hints}=${encodeURIComponent((hints||[]).join(','))}`
                }
              })
            }, 1000);
          } else {
            setTimeout(() => {
              this.setState({
                iframeDrawerParams: {
                  visible: true,
                  title: '新增模型',
                  url: `/data-govern/data-model-action?${Action}=add&${CatalogId}=${(currentView==='dir')?(catalogId||''):''}&${Hints}=${encodeURIComponent((hints||[]).join(','))}`
                }
              })
            }, 1000);
          }
        } else {
          if (currentView === 'requirement') {
            setTimeout(() => {
              this.setState({
                iframeDrawerParams: {
                  visible: true,
                  title: '新增模型',
                  url: `/data-govern/data-model-action?${Action}=add&${RequireId}=${catalogId||''}`
                }
              })
            }, 1000);
          } else {
            setTimeout(() => {
              this.setState({
                iframeDrawerParams: {
                  visible: true,
                  title: '新增模型',
                  url: `/data-govern/data-model-action?${Action}=add&${CatalogId}=${(currentView==='dir')?(catalogId||''):''}`
                }
              })
            }, 1000);
          }
        }
      }
    });
  }

  onImportModalCancelByWord = (refresh = false, wordData = {}) => {
    const { catalogId, currentView } = this.state;

    this.setState({ importModalVisible: false }, () => {
      refresh && this.onTableChange();

      if (wordData && ((wordData.msg||'')!=='')) {
        showNotifaction('提示', wordData.msg);
      }
  
      if (wordData && (wordData.content||[]).length > 0) {
        if ((wordData.content||[]).length > 5) {
          showMessage('info', '最多只能同时编辑5条信息');
        }

        if (currentView === 'requirement') {
          setTimeout(() => {
            wordData.content.slice(0, 5).forEach(data => {
              this.setState({
                iframeDrawerParams: {
                  visible: true,
                  title: '新增模型',
                  url: `/data-govern/data-model-action?${Action}=add&${RequireId}=${catalogId}&${ModelerData}=${encodeURIComponent(JSON.stringify(data))}`
                }
              })
            })
          }, 2000);
        } else {
          setTimeout(() => {
            wordData.content.slice(0, 5).forEach(data => {
              this.setState({
                iframeDrawerParams: {
                  visible: true,
                  title: '新增模型',
                  url: `/data-govern/data-model-action?${Action}=add&${CatalogId}=${catalogId}&${ModelerData}=${encodeURIComponent(JSON.stringify(data))}`
                }
              })
            })
          }, 2000);
        }
      }
    });
  }

  onImportModalCancelByDDL = (confirm = false, ddl = '') => {
    const { catalogId, currentView } = this.state;

    this.setState({ importModalVisible: false }, () => {
  
      if (confirm && (ddl||'') !== '') {
        if (currentView === 'requirement') {
          setTimeout(() => {
            this.setState({
              iframeDrawerParams: {
                visible: true,
                title: '新增模型',
                url: `/data-govern/data-model-action?${Action}=add&${RequireId}=${catalogId}&${DDL}=${encodeURIComponent(ddl)}`
              }
            })
          }, 1000);
        } else {
          setTimeout(() => {
            this.setState({
              iframeDrawerParams: {
                visible: true,
                title: '新增模型',
                url: `/data-govern/data-model-action?${Action}=add&${CatalogId}=${catalogId}&${DDL}=${encodeURIComponent(ddl)}`
              }
            })
          }, 1000);
        }
  
      }
    });
  }

  onImportStockWordDrawerCancel = () => {
    this.setState({ importStockWordDrawerVisible: false });
  }

  onImportStockWordSuccess = () => {
    this.onTableChange();
  }

  onExportDDLModalCancel = () => {
    this.setState({ exportDDLModalVisible: false });
  }

  onExportOtherModalCancel = (key='') => {
    const { selectModelerIds } = this.state;

    this.setState({ exportOtherModalVisible: false }, () => {
      if (key === 'ddl') {
        this.onExportDDLBtnClick();
      } else if (key === 'erwin') {
        dispatch({
          type: 'datamodel.exportERWinString',
          payload: {
            ids: selectModelerIds.join(','),
          },
          callback: data => {
            copy(JSON.stringify(data));
            showNotifaction('提示', 'Erwin信息已成功复制到剪贴板', 5);
          }
        });
      } else if (key === 'excel') {
        window.open(`/api/datamodeler/easyDataModelerExport/excel?ids=${selectModelerIds.join(',')}`);
      } else if (key === 'word') {
        window.open(`/api/datamodeler/easyDataModelerExport/word/template?ids=${selectModelerIds.join(',')}`);
      } else if (key === 'basicExcel') {
        window.open(`/api/datamodeler/easyDataModelerExport/modelBaseDataExcel?ids=${selectModelerIds.join(',')}`);
      } else if (key === 'upload') {
        dispatch({
          type: 'datamodel.uploadDDL',
          payload: {
            data: selectModelerIds
          },
          callback: () => {
            showMessage('success', '下发成功')
          }
        });
      }
    });
  }

  onRecatalogModalCancel = (refresh = false) => {
    this.setState({ recatalogModalVisible: false });
    if (refresh) {
      this.setState({ selectModelerIds: [] }, () => {
        this.onTableChange();
      });
    }
  }

  onBatchModelerCancel = (refresh = false) => {
    this.setState({ showBatchModeler: false });
    if (refresh) {
      this.setState({ selectModelerIds: [] }, () => {
        this.onTableChange();
      });
    }
  }

  onHistoryAndVersionDrawerCancel = () => {
    this.setState({ historyAndVersionDrawerVisible: false });
  }

  onStartFlowModalCancel = (refresh) => {
    this.setState({ startFlowModalVisible: false });

    if (refresh) {
      this.onTableChange();
      this.setState({ selectModelerIds: [] });
    }
  }

  importStockModel = () => {
    const { catalogId } = this.state;

    if ((catalogId||'') === '') {
      showMessage('info', '请先选择模型目录');
      return;
    }

    this.setState({ importStockWordDrawerVisible: true });
  }

  treeToggleClick = () => {
    this.setState({ expandTree: !this.state.expandTree });
  }

  onUnbindTipModalCancel = (refresh=false) => {
    const { selectModelerIds } = this.state;

    this.setState({ showUnbindTip: false });
    if (refresh) {
      dispatch({
        type: 'datamodel.requirementUnbind',
        payload: {
          data: {
            assocStringIdList: selectModelerIds,
            techJobId: this.state.catalogId
          },
        },
        callback: (tip) => {
          this.onTableChange();
          this.setState({ selectModelerIds: [] });
          showMessage('warn', '解绑成功');
        }
      })
    }
  }

  handleShowModeChange = (e) => {
    this.setState({ showMode: e.target.value })
  }

  render() {
    const { app } = this.props;
    const { importModalVisible, catalogId, loadingTableData, selectModelerIds, keyword, filterTableData, selectModelerNames, exportDDLModalVisible, exportOtherModalVisible, importStockWordDrawerVisible , loadingStates, modelStates, currentModelState, currentView, recatalogModalVisible, exportDDLModalReference, currentModel, offset, historyAndVersionDrawerVisible, modelerId, startFlowModalVisible, expandTree, showMode, tableData } = this.state;

    const content = (
      <ModelTable 
        loading={loadingTableData} 
        catalogId={catalogId} 
        view={currentView}
        data={filterTableData} 
        modelState={currentModelState}
        offset={offset}
        keyword={keyword}
        selectModelerIds={selectModelerIds}
        onChange={this.onTableChange} 
        onSelect={this.onTableSelect} 
        onItemAction={this.onTableItemAction} 
        onAutoCreateTable={this.onAutoCreateTable}
        onHistory={this.onHistory}
        {...this.props} />
    );

    const classes = classNames('data-model', {
      'data-model-collapse': !expandTree
    });  

    let disableStartFlow = false, startFlowTip = '', selectModelers = [];
 
    if ((selectModelerIds||[]).length===0) {
      disableStartFlow = true;
      startFlowTip = '请先选择模型';
    } else {
      selectModelerIds?.forEach(id => {
        let index = (tableData||[]).findIndex(item => item.id === id);
        if (index !== -1) {
          const modelItem = tableData[index];
          selectModelers.push(modelItem);

          if (modelItem.state?.id !== '1') {
            disableStartFlow = true;
            startFlowTip = '只有草稿状态下的模型才能送审';
          }
        }
      });
    }

    return (
      <div className={classes}>
        <div className='left'>
          <ModelTree onViewChange={this.onViewChange} onSelect={this.onTreeSelect} importStockModel={this.importStockModel} keyword={keyword} {...this.props} />
        </div> 
        <div className='tree-toggle-wrap'>
          <div className='tree-toggle' onClick={this.treeToggleClick}>
          { expandTree ? <CaretLeftOutlined /> : <CaretRightOutlined /> }
          </div>
        </div>
        <div className='right'>
          <div
            className='d-flex p-3'
            style={{
              borderBottom: '1px solid #EFEFEF',
              justifyContent: 'space-between',
              alignItems: 'center'
            }}
          > 
            {
              getDataModelerRole(app?.user)===DataModelerRoleReader ? <div /> : <Space>
                <Button onClick={() => { this.setState({ importModalVisible: true }); }}>新建</Button>
                <Tooltip title={(selectModelerIds||[]).length===0?'请先选择模型':''}>
                  <Button onClick={this.onExportOtherBtnClick} disabled={(selectModelerIds||[]).length===0}>导出</Button>
                </Tooltip>
                <Tooltip title={(selectModelerIds||[]).length===0?'请先选择模型':''}>
                  <Button onClick={this.onRecatalogBtnClick} disabled={(selectModelerIds||[]).length===0}>变更目录</Button>
                </Tooltip>
                <Tooltip title={(selectModelerIds||[]).length===0?'请先选择模型':''}>
                  <Button onClick={this.onBatchDeleteBtnClick} disabled={(selectModelerIds||[]).length===0}>删除</Button>
                </Tooltip>
                {
                  (currentView==='dir' || (currentView==='state'&&catalogId==='1')) && <Space>
                    <Tooltip title={startFlowTip}>
                      <Button onClick={this.startFlow} disabled={disableStartFlow}>送审</Button>
                    </Tooltip>
                  </Space>
                }
              </Space>
            }

            <Space> 
              {/* {
                !keyword && <Space>
                  <Radio.Group onChange={this.handleShowModeChange} value={showMode}>
                    <Radio.Button value="list">列表展示</Radio.Button>
                    <Radio.Button value="graph">图形展示</Radio.Button>
                  </Radio.Group>
                </Space>
              } */}
              {
                (currentView==='dir'||keyword!=='') && <Space>
                  <Select 
                    style={{ width: 120 }} 
                    onChange={(value) => {
                      this.onModelStateChange(value);
                    }}
                    loading={loadingStates}
                    value={loadingStates? '': currentModelState}
                  >
                  {
                    (modelStates||[]).map(item => {
                      return (
                        <Option key={item.id} value={item.id}>{item.cnName||''}</Option>
                      );
                    })
                  }
                  </Select>
                </Space>
              }     
              <Space>
                <InputDebounce 
                  placeholder="通过模型名称全文搜索" 
                  allowClear 
                  value={keyword}
                  onChange={(value) => { this.onSearchInputChange(value); }} 
                  style={{ width: inputWidth, marginLeft: 'auto' }}
                />
              </Space>

            </Space>

          </div>
          <div className='p-3'>
          {
            showMode==='list' ? <Spin spinning={loadingTableData}>
            { content }
            </Spin>: <MetadataAnalysis view={currentView} did={catalogId} sid={currentModelState} />
          } 
          </div>
        </div>

        <ImportModal 
          view={currentView}
          catalogId={catalogId}
          visible={importModalVisible} 
          onCancel={this.onImportModalCancel}
          onCancelByWord={this.onImportModalCancelByWord}
          onCancelByDDL={this.onImportModalCancelByDDL}
        />
        
        <ImportStockWordDrawer 
          visible={importStockWordDrawerVisible}
          onCancel={this.onImportStockWordDrawerCancel}
          catalogId={catalogId}
          onSuccess={this.onImportStockWordSuccess}
        />
        
        <AppContext.Consumer>
        {
          value => <ExportDDLModal 
            visible={exportDDLModalVisible}
            ids={selectModelerIds} 
            onCancel={this.onExportDDLModalCancel} 
          /> 
        }
        </AppContext.Consumer>

        <ExportOtherModal 
          visible={exportOtherModalVisible}
          onCancel={this.onExportOtherModalCancel}
        />

        <RecatalogModal
          visible={recatalogModalVisible}
          ids={selectModelerIds}
          onCancel={this.onRecatalogModalCancel}
        />

        <BatchModeler 
          id={catalogId}
          visible={this.state.showBatchModeler}
          onCancel={this.onBatchModelerCancel}
        />
        
        <HistoryAndVersionDrawer
          id={modelerId}
          visible={historyAndVersionDrawerVisible}
          onCancel={this.onHistoryAndVersionDrawerCancel}
        />

        <StartFlowModal
          items={selectModelers}
          visible={startFlowModalVisible}
          onCancel={this.onStartFlowModalCancel}
        />

        <DeleteTipModal
          visible={this.state.showUnbindTip}
          tip='您确定要解绑这些模型吗?'
          onCancel={this.onUnbindTipModalCancel}
        /> 

        <IframeDrawer
          {...this.state.iframeDrawerParams}
          onCancel={() => {
            this.setState({
              iframeDrawerParams: {
                visible: false,
                title: undefined,
                url: undefined
              }
            })
          }}
        />


      </div>
    );
  }

}

const Model = (props) => {
  const [modal, contextHolder] = Modal.useModal();
  const app = React.useContext(AppContext)

  return (
    <>
      <ModelComponet modal={modal} app={app} {...props} />
      {contextHolder}
    </>
  )
}

export default Model;
