import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Modal, Form, TreeSelect, Select, Space, Button, Row, Col, Tabs, Spin, Input } from 'antd';

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

const AddSourceModelName = '新增数据来源'

const MetaModelSelect = ({ value = {}, metaModelTreeData = [], onChange, ...restProps }) => {
  const [ attributes, setAttributes ] = useState([]);
  const [ loading, setLoading ] = useState(false);

  useEffect(() => {
    if ((value?.model||'') !== '') {
      getAttributesByMetadataModel(value?.model);
    } else {
      setAttributes([]);
    }
  }, [value?.model])

  const onTreeChange = (value, label, extra) => { 
    if ((label||[]).length > 0) {
      triggerChange({ modelValue: value, model: label[0], attrName: '', attrCnName: '' });
    } else {
      triggerChange({ modelValue: '', model: '', attrName: '', attrCnName: '' });
    }
  }

  const onAttributeChange = (value) => {

    if ((value||'') === '') {
      triggerChange({ attrName: '', attrCnName: '' });
      return;
    }

    const index = (attributes||[]).findIndex(attribute => attribute.name===value);

    if (index !== -1) {
      triggerChange({ attrName: attributes[index]?.name, attrCnName: attributes[index]?.cnName });
    } 
  }

  const triggerChange = (changedValue) => {
    onChange?.({
      ...value,
      ...changedValue,
    });
  };

  const getAttributesByMetadataModel = (model) => {
    setLoading(true);
    dispatch({
      type: 'assetmanage.getAttributesByMetadataModel',
      payload: {
        modelName: model
      },
      callback: data => {
        setLoading(false);
        setAttributes(data||[]);
      },
      error: () => {
        setLoading(false);
      }
    });
  }

  //value有可能为空
  value = value ? value: {};

  return (
    <Row gutter={10}>
      <Col span={12}>
        <TreeSelect
          value={value.modelValue}
          placeholder='请选择元模型'
          treeData={metaModelTreeData}
          onChange={onTreeChange}
          allowClear
        />
      </Col>
      <Col span={12}>
        <Select 
          onChange={(value) => { onAttributeChange && onAttributeChange(value) }} 
          value={value.attrName} 
          loading={loading}
          placeholder='请选择属性'
          allowClear
        >
        {
          (attributes||[]).map((attribute, index) => {
            return (
              <Select.Option key={index} value={attribute.name||''}>
              { attribute.cnName||'' }
              </Select.Option>
            );
          })
        }
        </Select>
      </Col>
    </Row>
  );
}

const AttributeRelationWithSourceModel = (props) => {
  const { elements, sourceModel, supportSourceModelsName, metadataModelTreeData, activeKey, onChange  } = props;
  
  const [ loading, setLoading ] = useState(false)
  const [ confirmLoading, setConfirmLoading ] = useState(false);
  const [ currentRelations, setCurrentRelations ] = useState();

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

  useEffect(() => {
    if (sourceModel) {
      getRelAttrBySourceModel()
    } else {
      form.resetFields()
    }

    form.setFieldsValue({ sourceModel })
  }, [activeKey, sourceModel])

  useEffect(() => {
    if (currentRelations && elements?.length > 0) {
      let newFiledsValue = {};
      (currentRelations||[]).forEach(item => {
        newFiledsValue[item.elementId] = {model: item.model, modelValue: item.model, attrName: item.attrName||'', attrCnName: item.attrCnName||''};
      })

      form.setFieldsValue(newFiledsValue);
    }
  }, [currentRelations, elements])

  const getRelAttrBySourceModel = () => {
    setLoading(true)
    dispatch({
      type: 'assetmanage.getRelAttrBySourceModel',
      payload: {
        sourceModel
      },
      callback: data => {
        setLoading(false)
        setCurrentRelations(data||[])
      },
      error: () => {
        setLoading(false)
      }
    });
  }

  const onDelete = () => {
    modal.confirm({
      title: '提示!',
      content: '您确定要删除该来源模型名称吗?',
      onOk: () => {
        dispatch({
          type: 'assetmanage.deleteRelAttrBySourceModel',
          payload: {
            params: {
              sourceModel
            }
          },
          callback: () => {
            showMessage('success', '删除成功')
            onChange?.('delete')
          }, 
          error: () => {
            
          }
        });
      }
    });
  }

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

      let newRels = [];
      for (var key in row) {
        if ((row[key]||'') !== '') {
          if ((row[key]?.model||'')!=='' && (row[key]?.attrName||'')!=='') {
            newRels.push({ elementId: key, model: row[key]?.model, attrName: row[key]?.attrName||'', attrCnName: row[key]?.attrCnName||''});
          }
        }
      }

      setConfirmLoading(true);

      dispatch({
        type: 'assetmanage.saveEleAndAttrRelWithSourceModel',
        payload: {
          data: newRels,
          params: {
            sourceModel: row.sourceModel,
          }
        },
        callback: data => {
          showMessage('success', sourceModel?'更新成功':'新增成功')
          setConfirmLoading(false);
          onChange?.('update', row.sourceModel)
        },
        error: () => {
          setConfirmLoading(false);
        }
      });

    } catch (errInfo) {
      console.log('Validate Failed:', errInfo);
      setConfirmLoading(false);
    }
  }

  const formItemLayout = {
    labelCol: {
      xs: { span: 24 },
      sm: { span: 5 },
    },
    wrapperCol: {
      xs: { span: 24 },
      sm: { span: 17 },
    },
  };

  return <Spin spinning={loading}>
    <div className='mb-3' style={{ textAlign: 'right' }}>
      <Space>
        {
          sourceModel && <Button type="primary" danger onClick={() => onDelete()}>删除</Button>
        }
        <Button type="primary" onClick={() => onOk()} loading={confirmLoading}>确定</Button>
      </Space>
    </div>
    <Form form={form} style={{ maxHeight: 400, overflow: 'auto' }} {...formItemLayout}> 
      <Form.Item 
        label='来源模型名称' 
        name='sourceModel' 
        rules={[{ required: true, message: '请输入来源名称'}]}
      >
        <Select 
          allowClear
          placeholder='请选择来源模型名称'
          disabled={sourceModel}
        >
        {
          supportSourceModelsName?.map((name, index) => {
            return <Select.Option key={index} value={name}>
            { name }
            </Select.Option>
          })
        }
        </Select>
      </Form.Item>
      {
        (elements||[]).map((element, index) => {
          return (
            <Form.Item 
              label={element.name||''} 
              name={element.id||''} 
              key={index}
            >
              <MetaModelSelect
                metaModelTreeData={metadataModelTreeData}
              />
            </Form.Item>
          );
        })
      }
    </Form>
    {contextHolder}
  </Spin>
}

const AttributeRelationModal = (props) => {
  const { visible, onCancel } = props;

  const [ supportSourceModelsName, setSupportSourceModelsName ] = useState()
  const [ loadingSourceModels, setLoadingSourceModels] = useState(false)
  const [ sourceModels, setSourceModels ] = useState()
  const [ metadataModelTreeData, setMetadataModelTreeData ] = useState([]);
  const [ elements, setElements] = useState([]);
  const [ activeKey, setActiveKey ] = useState();

  const activeKeyRef = useRef();

  useEffect(() => {
    if (visible) {
      getSupportSourceModelsName();
      getSourceModels();
      loadElementWithoutCustom();
      getMetadataModelTree();
    }
    //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [visible])

  const tabData = useMemo(() => {
    return [...sourceModels||[], AddSourceModelName]
  }, [sourceModels])

  const getSupportSourceModelsName = () => {
    dispatch({
      type: 'assetmanage.listSupportSourceModels',
      callback: (data) => {
        console.log('data', data)
        setSupportSourceModelsName(data||[])
      },
    })
  }

  const getSourceModels = () => {
    setLoadingSourceModels(true)
    dispatch({
      type: 'assetmanage.listSourceModels',
      callback: (data) => {
        setLoadingSourceModels(false)
        setSourceModels(data||[])

        if (!activeKeyRef.current) {
          activeKeyRef.current = data?.length > 0 ? data[0] : AddSourceModelName
          setActiveKey(data?.length > 0 ? data[0] : AddSourceModelName)
        } else if (activeKeyRef.current !== activeKey) {
          setActiveKey(activeKeyRef.current)
        }
      },
      error: () => {
        setLoadingSourceModels(false)
      }
    })
  }

  const getMetadataModelTree = () => {
    dispatch({
      type: 'assetmanage.getMetadataModelTree',
      callback: data => {
        let newData = [...data];
        
        function recursion(_data, superKey='') {

          if ((_data||[]).length===0) return;

          (_data||[]).forEach(item=> {
            item.title = item.nodeName||'';
            item.value = superKey + '/' +(item.nodeName||'');

            recursion(item.children, item.value);
          })
        } 

        recursion(newData);
        setMetadataModelTreeData(newData||[]);
      },
      error: () => {
      }
    });
  }

  const loadElementWithoutCustom = () => {
    dispatch({
      type: 'assetmanage.loadElementWithoutCustom',
      callback: data => {
        setElements(data||[]);
      },
      error: () => {
        
      }
    });
  }

  const onTabsChange = (value) => {
    activeKeyRef.current = value
    setActiveKey(value)
  }

  const onRelationChange = (type, value) => {
    if (type === 'delete') {
      activeKeyRef.current = undefined
      getSourceModels()
    } else if (type === 'update') {
      activeKeyRef.current = value
      getSourceModels()
    }
  }

  const reset = () => {
    setActiveKey(undefined);
  }

  return (
    <Modal
      forceRender
      title={'资产目录属性关联'}
      visible={visible}
      width={1000}
      onCancel={() => { 
        reset();
        onCancel?.();
      }}
      footer={
        <Space>
          <Button onClick={() => {
            reset();
            onCancel?.();
          }}>取消</Button>
        </Space>
      }
    >
      <Tabs tabPosition='left' activeKey={activeKey} onChange={onTabsChange}>
      {
        tabData?.map((item, i) => {
          return <Tabs.TabPane tab={item} key={item}>
            <AttributeRelationWithSourceModel 
              elements={elements} 
              supportSourceModelsName={supportSourceModelsName}
              metadataModelTreeData={metadataModelTreeData} 
              sourceModel={item === AddSourceModelName ? undefined: item}
              activeKey={activeKey}
              onChange={onRelationChange}
            />
          </Tabs.TabPane>
        })
      }
      </Tabs>
    </Modal>  
  );
}

export default AttributeRelationModal;