import React from 'react';
import { Modal, Button, Select, Input } from 'antd';

import { showMessage } from '../../../../util';
import { dispatch } from '../../../../model';

const { Option } = Select;

class ExportDDLModal extends React.Component {

  constructor() {
    super();
    this.state = {
      loadingDDLGenerators: false,
      ddlGenerators: [],
      selectDDLGeneratorName: null,
      selectModalerNameKey: 0,
      confirmLoading: false,
      ddlExportSuccess: false,
      ddlExportStrings: [],
      ddlExportString: '',
      loadingDatabases: false,
      databases: [],
      filterDatabases: [],
      currentDatabaseId: '',
      loadingSchemas: false,
      schemas: [],
      currentSchemaId: ''
    }
  }

  componentDidMount() {

    this.init();
  }

  componentDidUpdate(preProps, preState) {
    const { visible } = this.props;
    if (visible!==preProps.visible && visible) {
      this.init();
    } 
  }

  init = () => {
    const { reference = 'exportDDL' } = this.props;

    if (reference === 'exportDDL') {
      this.getDDLGenerators();
    } else if (reference === 'createTable') {
      this.getDDLGeneratorsThenGetAllDatasource();
    }
  }

  getDDLGeneratorsThenGetAllDatasource = () => {
    this.getDDLGenerators(true);
  }

  getDDLGenerators = (needDB = false) => {
    this.setState({ loadingDDLGenerators: true }, () => {
      dispatch({
        type: 'datamodel.ddlGenerators',
        callback: data => {
          this.setState({ ddlGenerators: data, loadingDDLGenerators: false, selectDDLGeneratorName: (data||[]).length>0?data[0].name:'' }, () => {
            if (needDB) {
              this.getDatabases();
            }
          });
        }, 
        error: () => {
          this.setState({ loadingDDLGenerators: false });
        }
      });
    })
  }

  getDatabases = () => {
    const { env } = this.props;
    const { selectDDLGeneratorName } = this.state;

    console.log('env', env);

    this.setState({ loadingDatabases: true }, () => {
      dispatch({
        type: 'datamodel.getDatasourcesByEnv',
        payload: {
          catalog: env?.value,
          model: 'Catalog,Database'
        },
        callback: data => {

          let _filterData = [];
  
          if (selectDDLGeneratorName === 'Greenplum') {
            _filterData = data.filter(item => item.databaseType==='PostgreSQL');
          } else if (selectDDLGeneratorName === 'MySQL') {
            _filterData = data.filter(item => item.databaseType==='MySQL');
          }

          this.setState({ loadingDatabases: false, databases: data, filterDatabases: _filterData, currentDatabaseId: ((_filterData||[]).length>0)?_filterData[0]._id:'' }, () => {
            if ((_filterData||[]).length>0) {
              this.getSchemas(_filterData[0]?._id);
            } else {
              this.setState({ schemas: [], currentSchemaId: '' });
            }
          });
        }, 
        error: () => {
          this.setState({ loadingDatabases: false });
        }
      });
    })
  }

  getSchemas = (dbId) => {
    this.setState({ loadingSchemas: true }, () => {
      dispatch({
        type: 'datamodel.getSchemasByDatasourceId',
        payload: {
          parentId: dbId||''
        },
        callback: data => {
          this.setState({ loadingSchemas: false, schemas: data, currentSchemaId: (data||[]).length>0?data[0]._id:'' });
        }, 
        error: () => {
          this.setState({ loadingSchemas: false });
        }
      });
    })
  }

  generatorDDLStrings = () => {
    const { ids, reference } = this.props;
    const { ddlGenerators, loadingDDLGenerators, selectDDLGeneratorName, currentSchemaId } = this.state;

    if (loadingDDLGenerators) {
      showMessage('info', '正在加载ddl支持的数据库类型');
      return;
    }

    if ((ddlGenerators||[]).length===0) {
      showMessage('info', 'ddl支持的数据库类型没有查找到,重新查找中');
      this.getDDLGenerators();
      return;
    }

    if (!selectDDLGeneratorName || selectDDLGeneratorName==='') {
      showMessage('info', '请选择ddl支持的数据库类型');
      return;
    }

    if (reference==='createTable' && (currentSchemaId||'')==='') {
      showMessage('info', '请选择Schema');
      return;
    }

    this.setState({ confirmLoading: true }, () => {
      dispatch({
        type: 'datamodel.exportDDLString',
        payload: {
          ids: ids.join(','),
          ddlGeneratorName: selectDDLGeneratorName
        },
        callback: data => {
          this.setState({ confirmLoading: false }, () => {
            this.setState({ ddlExportSuccess: true, ddlExportStrings: data||[], selectModalerNameKey: 0, ddlExportString: data[0]||'' });
          });
        }, 
        error: () => {
          this.setState({ confirmLoading: false });
        }
      });
    })

  }

  createTable = () => {
    const { onCancel } = this.props;
    const { databases, schemas, currentDatabaseId, currentSchemaId, ddlExportStrings, selectDDLGeneratorName } = this.state;
    
    let _currentDatabase = {}, _currentSchema = {};

    (databases||[]).forEach(item => {
      if (item._id === currentDatabaseId) {
        _currentDatabase = item;
      }
    });

    (schemas||[]).forEach(item => {
      if (item._id === currentSchemaId) {
        _currentSchema = item;
      }
    });

    let namespace = '', scope = '', dbType = '';
    if ((_currentSchema?.namePathList||[]).length>0) {
      namespace = _currentSchema.namePathList[0];
    }
    if ((_currentSchema?.sysList||[]).length>0) {
      scope = _currentSchema.sysList[0];
    }

    if (selectDDLGeneratorName === 'Greenplum') {
      dbType = 'PGTarget';
    } else if (selectDDLGeneratorName === 'MySQL') {
      dbType = 'MysqlTarget';
    }

    this.setState({ confirmLoading: true }, () => {
      dispatch({
        type: 'datamodel.autoCreateTable',
        payload: {
          params: {
            namespace,
            scope,
            dataSourceName: _currentDatabase?.name,
            schema: _currentSchema?.name,
            dbType,
          },
          data: ddlExportStrings
        },
        callback: () => {
          this.setState({ confirmLoading: false });
          this.reset();
          onCancel && onCancel();
        }, 
        error: () => {
          this.setState({ confirmLoading: false });
        }
      });
    })

  }

  reset = () => {
    this.setState({ ddlExportSuccess: false, ddlExportStrings: [] });
  }

  onModalerNameChange = (value) => {
    const { ddlExportStrings } = this.state;
    this.setState({ selectModalerNameKey: value, ddlExportString: ddlExportStrings[value]||'' });
  }

  onDDLGeneratorChange = (value) => {
    this.setState({ selectDDLGeneratorName: value||'' }, () => {
      this.getDatabases();
    });
  }

  onDatabaseChange = (value) => {
    this.setState({ currentDatabaseId: value||'' }, () => {
      this.getSchemas(value);
    });
  }

  onSchemaChange = (value) => {
    this.setState({ currentSchemaId: value||'' });
  }

  onDDLStringChange = (e) => {
    const { reference = 'exportDDL' } = this.props;
    const { ddlExportStrings, selectModalerNameKey } = this.state;

    if (reference === 'createTable') {
      const _newDDLExportStrings = [...ddlExportStrings];
      _newDDLExportStrings[selectModalerNameKey] = e.target.value;

      this.setState({ ddlExportString: e.target.value||'', ddlExportStrings: _newDDLExportStrings });
    }
  }

  render() {
    const { visible, onCancel, names, ids, reference } = this.props;
    const { ddlGenerators, loadingDDLGenerators, confirmLoading, selectDDLGeneratorName, ddlExportSuccess, ddlExportString, selectModalerNameKey, loadingDatabases, loadingSchemas, schemas, currentDatabaseId, currentSchemaId, filterDatabases } = this.state;

    let title = '';
    if (reference === 'exportDDL') {
      title = ddlExportSuccess ? 'DDL导出详情' : 'DDL导出';
    } else if (reference === 'createTable') {
      title = ddlExportSuccess ? '模型自动建表详情' : '模型自动建表';
    }

    let footer = null;
    if (reference === 'exportDDL') {
      footer = ddlExportSuccess ? ([
        <Button
          key="0" 
          onClick={() => {
            this.reset();
            onCancel && onCancel();
          }}
        >
        取消
        </Button>,
        <Button
          key="1" 
          type="primary"
          onClick={() => {
            window.open(`/api/datamodeler/easyDataModelerExport/ddlStringAsFile?ids=${ids.join(',')}&ddlGeneratorName=${selectDDLGeneratorName}`);
            this.reset();
            onCancel && onCancel();
          }}
        >
        导出到文件
        </Button>
      ]) : ([
        <Button
          key="0" 
          onClick={() => {
            this.reset();
            onCancel && onCancel();
          }}
        >
        取消
        </Button>,
        <Button
          key="1" 
          type="primary"
          onClick={this.generatorDDLStrings}
        >
        预览
        </Button>
      ])
    } else if (reference === 'createTable') {
      footer = ddlExportSuccess ? ([
        <Button
          key="0" 
          onClick={() => {
            this.reset();
            onCancel && onCancel();
          }}
        >
        取消
        </Button>,
        <Button
          key="1" 
          type="primary"
          onClick={this.createTable}
        >
        建表
        </Button>
      ]) : ([
        <Button
          key="0" 
          onClick={() => {
            this.reset();
            onCancel && onCancel();
          }}
        >
        取消
        </Button>,
        <Button
          key="1" 
          type="primary"
          onClick={this.generatorDDLStrings}
        >
        预览
        </Button>
      ])
    }

    return (
      <Modal 
        visible={visible}
        title={title}
        loading={confirmLoading}
        onCancel={() => {
          this.reset();
          onCancel && onCancel();
        }}
        footer={footer}
      > 
        <React.Fragment>
        {
          ddlExportSuccess ? <React.Fragment>
            <div className='d-flex mb-5' style={{ alignItems: 'center' }}>
              <span className='mr-2'>模型名称:</span>
              <Select 
                value={selectModalerNameKey}
                style={{ width: 180 }} 
                placeholder='请选择模型名称'
                onChange={this.onModalerNameChange}
              >
              {
                names && names.map((name, index) => {
                  return <Option key={index} value={index}>{name||''}</Option>
                })
              }
              </Select>
            </div>
            <Input.TextArea value={ddlExportString||''} autoSize={{minRows:4,maxRows:20}} onChange={this.onDDLStringChange} ></Input.TextArea>
          </React.Fragment> : <React.Fragment> 
            <div className='d-flex' style={{ alignItems: 'center' }}>
              <span className='mr-2' style={{ width: 85 }}>数据库类型: </span>
              <Select 
                value={selectDDLGeneratorName}
                loading={loadingDDLGenerators}
                style={{ width: 180 }} 
                placeholder='请选择数据库类型'
                onChange={this.onDDLGeneratorChange}
              >
              {
                ddlGenerators && ddlGenerators.map((ddlGenerator, index) => {
                  return <Option key={index} value={ddlGenerator.name||''}>{ddlGenerator.cnName||''}</Option>
                })
              }
              </Select>
            </div>
            {
              reference==='createTable' && <React.Fragment>
                <div className='d-flex mt-3' style={{ alignItems: 'center' }}>
                  <span className='mr-2' style={{ width: 85 }}>数据源名称:</span>
                  <Select 
                    value={currentDatabaseId}
                    style={{ width: 180 }} 
                    placeholder='请选择数据源名称'
                    onChange={this.onDatabaseChange}
                    loading={loadingDatabases}
                  >
                  {
                    filterDatabases && filterDatabases.map((item, index) => {
                      return <Option key={index} value={item._id}>{item.name||''}</Option>
                    })
                  }
                  </Select>
                </div>
                <div className='d-flex mt-3' style={{ alignItems: 'center' }}>
                  <span className='mr-2' style={{ width: 85 }}>Schema名称:</span>
                  <Select 
                    value={currentSchemaId}
                    style={{ width: 180 }} 
                    placeholder='请选择Schema名称'
                    onChange={this.onSchemaChange}
                    loading={loadingSchemas}
                  >
                  {
                    schemas && schemas.map((item, index) => {
                      return <Option key={index} value={item._id}>{item.name||''}</Option>
                    })
                  }
                  </Select>
                </div>
              </React.Fragment>
            }
          </React.Fragment>
        }
        </React.Fragment>
      </Modal>
    )
  }
}

export default ExportDDLModal;