import React, { useState, useEffect } from 'react';
import { Modal, Button, AutoComplete, Input, Avatar, TreeSelect, Form, Select } from 'antd';

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

import './AddTagModal.less';

const { Option } = Select;

const ClassifySelect = ({ value = '', data = [], onChange, ...restProps }) => {

  const onClassifyChange = (value) => {
    onChange((value||[]).join(','));
  }

  return (
    <Select
      mode="multiple"
      value={value?value.split(','):[]}
      onChange={onClassifyChange}
      allowClear
      style={{ width: '100%' }}
    >
    {
      (data?.tagClassifyNodes||[]).map((item, index) => {
        return (
          <Option key={item.id}>{item.cnName||''}</Option>
        );
      })
    }
    </Select>
  )
}

const AddTagModal = (props) => {
  const { visible, onCancel, id, type, creator, onAssetTag } = props;

  const [ step, setStep ] = useState(0);
  const [ keyword, setKeyword ] = useState('');
  const [ selectTag, setSelectTag ] = useState(null);
  const [ matchTags, setMatchTags ] = useState([]);
  const [ options, setOptions ] = useState();
  const [ confirmLoading, setConfirmLoading ] = useState(false);
  const [ tagForm, setTagForm ] = useState({});

  const [form] = Form.useForm();

  useEffect(() => {

    if (visible) {
      getTagByKeywordAndCreator();
      getSupportTagForm();
    }

  //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ visible ])

  const getTagByKeywordAndCreator = (value=keyword) => {
    dispatch({
      type: 'tag.getTagByKeywordAndCreator',
      payload: {
        keyword: value,
        creator,
      },
      callback: data => {
        setMatchTags(data||[]);

        let tagExsit = false, _selectTag = null;
        const _options = [];
        (data||[]).forEach(item => {
          _options.push({
            value: item.tagId,
            label: (
              <div
                style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                }}
              >
                {item.name||''}
                <Avatar 
                  shape="square" 
                  size="small"
                  title={item.type==='public'?'公共标签':'个人标签'}
                >
                  {item.type==='public'?'公':'个'}
                </Avatar>
              </div>
            )
          });

          if (value==='' || item.name===value) {
            tagExsit = true;
          }

          if (item.name === value) {
            _selectTag = item;
          }

        })

        if (!tagExsit) {
          _options.push({
            value: -1,
            label: (
              <a >{`创建 ${value||''}`}</a>
            )
          })
        }

        setSelectTag(_selectTag);
        setOptions(_options);
      }
    })
  }

  const getSupportTagForm = () => {
    dispatch({
      type: 'tag.getSupportTagForm',
      payload: {
        isDefault: false,
        type: 'private',
        creator
      },
      callback: data => {
        setTagForm(data||{});
      }
    })
  }

  const onOk = () => {
    if (keyword === '') {
      showMessage('warn', '请先填写标签');
      return;
    }

    setConfirmLoading(true);
    dispatch({
      type: 'assetmanage.listDirectoryByName',
      payload: {
        name: keyword
      },
      callback: data => {
        setConfirmLoading(false);

        if ((data||[]).length===0) {
          if (selectTag) {
            setConfirmLoading(true);
            dispatch({
              type: 'tag.batchAddTagResource',
              payload: {
                params: {
                  tagId: selectTag.tagId,
                  resourceIds: id,
                  type,
                  creator
                }
              },
              callback: () => {
                reset();
                onCancel && onCancel(true);
              },
              error: () => {
                setConfirmLoading(false);
              }
            })
          } else {
            setStep(1);
          }
        } else {
          reset();
          onAssetTag && onAssetTag(keyword);
        }
      },
      error: () => {
        setConfirmLoading(false);
      }
    })
  }

  const cancel = () => {
    reset();
    onCancel && onCancel();
  }

  const onBack = () => {
    setStep(0);
  }

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

      const newTagForm = JSON.parse(JSON.stringify(tagForm));
      (newTagForm?.targetParameters||[]).forEach(param => {
        param.value = row[param.name];
      })

      setConfirmLoading(true);
      dispatch({
        type: 'tag.saveTag',
        payload: {
          params: {
            isDefault: false
          },
          data: newTagForm
        },
        callback: data => {
          dispatch({
            type: 'tag.batchAddTagResource',
            payload: {
              params: {
                tagId: data.id,
                resourceIds: id,
                type,
                creator
              }
            },
            callback: () => {
              reset();
              onCancel && onCancel(true);
            },
            error: () => {
              setConfirmLoading(false);
            }
          })
        },
        error: () => {
          setConfirmLoading(false);
        }
      })

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

  const onKeywordChange = (value) => {
    //匹配行被选中时 跳过
    if (value!==undefined && value!==null && typeof(value)!=='string') return;

    setSelectTag(null);
    setKeyword(value||'');
    getTagByKeywordAndCreator(value||'');
  }

  const onSelect = (value, option) => {
    if (value!==-1) {
      let _selectTag = null;

      matchTags.forEach(item => {
        if (item.tagId === value) {
          _selectTag = item;
        }
      })

      setSelectTag(_selectTag);
      setKeyword(_selectTag.name||'');
    } else {
      setSelectTag(null);
      setStep(1);
    }
  }

  const reset = () => {
    setConfirmLoading(false);
    form.resetFields();
    setStep(0);
    setSelectTag(null);
    setKeyword('');
  }

  const loop = (data) =>
    data.map(item => {
      if ((item.children||[]).length>0) {
        return { ...item, ...{title: item.name, value: item.idString, children: loop(item.children)} };
      }

      return { ...item, ...{ title: item.name, value: item.idString }};
    });

  const formItemLayout = {
    labelCol: {
      xs: { span: 24 },
      sm: { span: 4 },
    },
    wrapperCol: {
      xs: { span: 24 },
      sm: { span: 20 },
    },
  };

  let footer = [];

  if (step === 0) {
    footer = [ 
      <Button
        key="0" 
        onClick={cancel}
      >
      取消
      </Button>,
      <Button
        key="1" 
        type="primary"
        loading={confirmLoading}
        onClick={onOk}
        disabled={keyword===''}
      >
      确定
      </Button>
    ];
  } else if (step === 1) {
    footer = [ 
      <Button
        key="0" 
        onClick={onBack}
      >
      返回
      </Button>,
      <Button
        key="1" 
        type="primary"
        loading={confirmLoading}
        onClick={onCreate}
      >
      创建
      </Button>
    ];
  }

  return (
    <Modal 
      className='add-tag-modal'
      forceRender
      visible={visible}
      title={(step===0)?'新建标签':`创建${keyword}`}
      width={520}
      onCancel={cancel}
      footer={footer}
    >
    {
      step === 0 && <AutoComplete
        style={{ width: '100%' }}
        allowClear 
        value={keyword}
        onChange={onKeywordChange}
        options={options}
        onSelect={onSelect}
      />
    }
    {
      step === 1 && <Form 
        {...formItemLayout}
        form={form}
        initialValues={{ name: keyword }}
      > 
      {
        (tagForm?.targetParameters||[]).map((param, index) => {

          if (param.name === 'usable') return null;

          let itemComponent = (
            <Input disabled={param.name==='name'} />
          );
          
          if (param.selectMode==='singleSelect') {
            itemComponent = (
              <TreeSelect 
                style={{ width: '100%' }}
                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} 
                treeData={loop(param?.tagCatalogNode?.children||[])}
                treeDefaultExpandAll 
                allowClear
              />
            );
          } else if (param.selectMode==='multiSelect') {
            itemComponent = (
              <ClassifySelect
                data={param}
              />
            );
          }

          return (
            <Form.Item
              key={index}
              label={param.cnName||''}
              name={param.name||''}
              rules={[{ required: param.required, message: `请选择${param.cnName}!` }]}
            >
            { itemComponent }
            </Form.Item>
          );
        })
      }
      </Form>
    }
    </Modal>
  )
}

export default AddTagModal;