import React, { useState, useEffect } from 'react';
import { Form, Typography, Button, Select, Row, Col, Tooltip, Table } from 'antd';
import { DeleteOutlined } from '@ant-design/icons';

import { showMessage, highlightSearchContentByTerms } from '../../../../util';

const { Option } = Select;

const PartitionTypeInput = ({ value = {}, partitionTypes, onChange }) => {

  const onNameChange = (value) => {

    let currentPartitionType = {}; 
    (partitionTypes||[]).forEach((partitionType, index) => {
      if (value === partitionType.name) {
        currentPartitionType = partitionType;
      }
    })

    triggerChange(currentPartitionType);
  }

  const triggerChange = (changedValue) => {
    onChange && onChange(changedValue);
  };

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

  return (
    <>
      <Row align='middle'>
        <Col span={9}>
          <span>名称:</span>
        </Col>
        <Col span={15}>
          <Select 
            onChange={onNameChange} 
            value={value.name || ''} 
            placeholder='请选择类型名称'
          >
          {
            (partitionTypes||[]).map((partitionType, index) => {
              return (
                <Option key={partitionType.name||''}>{partitionType.name||''}</Option>
              );
            })
          }
          </Select>
        </Col>
      </Row> 
    </>
  )
}

const AttributesInputItem = ({ indexedAttribute = null, attributes, onAttributeChange, onDelete , className }) => {

  return (
    <Row align='middle' className={className} >
      <Col span={4}>
        <span>字段名称:</span>
      </Col>
      <Col span={6}>
        <Select 
          onChange={(value) => { onAttributeChange && onAttributeChange(value) }} 
          value={indexedAttribute ? (indexedAttribute.name||'') : ''} 
          placeholder='请选择字段名称'
        >
        {
          (attributes||[]).map((attribute, index) => {
            return (
              ((attribute.name||'')==='') ? null : <Option key={index} value={attribute.iid||''}>{attribute.name||''}</Option>
            );
          })
        }
        </Select>
      </Col>
      <Col span={1}></Col>
      <Col span={1}>
        <Tooltip title="删除">
          <Button type="text" icon={<DeleteOutlined />} onClick={onDelete} />
        </Tooltip>
      </Col>
    </Row> 
  );
}

const AttributesInput = ({ value = [], attributes, onChange }) => {
  
  const indexedEasyDataModelAttributes = value;

  const onAttributeChange = (value, index) => {

    if (indexedEasyDataModelAttributes.findIndex(item => item.iid === value) !== -1) {
      showMessage('warn', '字段不能重复选择');
      return;
    }

    const newIndexedEasyDataModelAttributes = [...indexedEasyDataModelAttributes];

    const _index = attributes.findIndex(item => item.iid === value);
    newIndexedEasyDataModelAttributes.splice(index, 1, {...attributes[_index]});
    triggerChange(newIndexedEasyDataModelAttributes);
  }

  const onItemDelete = (index) => {
    const newIndexedEasyDataModelAttributes = [...indexedEasyDataModelAttributes];

    newIndexedEasyDataModelAttributes.splice(index, 1);

    if (newIndexedEasyDataModelAttributes.length === 0) {
      newIndexedEasyDataModelAttributes.push({});
    }

    triggerChange(newIndexedEasyDataModelAttributes);
  }

  const addAttribute = () => {
    triggerChange([...indexedEasyDataModelAttributes, {}])
  }

  const triggerChange = (changedValue) => {
    onChange && onChange(changedValue);
  };

  return (
    <>
      {
        (indexedEasyDataModelAttributes||[]).map((indexedAttribute, index) => {
          return (
            <AttributesInputItem 
              key={index}
              className='mb-2'
              indexedAttribute={indexedAttribute}
              attributes={attributes}
              onAttributeChange={(value) => { onAttributeChange(value, index) } }
              onDelete={() => { onItemDelete(index) }}
            />
          );
        })
      }
      <Button onClick={addAttribute}>新增字段</Button>
    </>
  )
}

const EditableCell = ({
  editing,
  dataIndex,
  colTitle,
  inputType,
  record,
  index,
  attributes,
  partitionTypes,
  children,
  ...restProps
}) => {

  let editingComponent = null;
  if (editing) {
    editingComponent = (
      <Form.Item
        name={dataIndex}
        style={{
          margin: 0,
        }}
        valuePropName={'value'}
        rules={[
          {
            required: true,
            message: `请输入${colTitle}!`,
          },
        ]}
        >
      { (dataIndex==='keys') ? <AttributesInput attributes={attributes} /> : <PartitionTypeInput partitionTypes={partitionTypes} /> }
      </Form.Item>
    )
  }


  return (
    <td {...restProps}>
      {editing ? (
        editingComponent
      ) : (
        children
      )}
    </td>
  );
};

const ImportActionPartition = (props) => {
  const { modelerData, onChange, editable, constraint, template, terms, supportedPartitionTypes } = props;

  const [ attributes, setAttributes ] = useState([]);
  const [ data, setData ] = useState(null);

  const [ form ] = Form.useForm();
  const [ isEditing, setIsEditing ] = useState(false);
  
  //规则改变的时候 数据表为可编辑状态
  useEffect(() => {
    setIsEditing(false);
  }, [constraint, template, modelerData])

  useEffect(() => {

    setAttributes(modelerData.easyDataModelerDataModelAttributes||[]);

    setData(modelerData?.partition);

  }, [modelerData])
  
  const onAddClick = () => {

    if (!data) {
      setData({
        partitionType: {},
        keys: [],
      });
      form.setFieldsValue({
        type: {},
        keys: [],
      });

      setIsEditing(true);
    }
  }

  const edit = (record) => {
    form.setFieldsValue({type: record.partitionType, keys: record.keys});
    setIsEditing(true);
  }

  const remove = (record) => {
    setData(null);
    onChange && onChange(null);
  }

  const cancel = () => {
    setIsEditing(false);
    if (!data?.partitionType?.name) {
      setData(null);
    }
  };

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

      if (!row.type?.name) {
        form.setFields([{ name: 'type', errors: ['必须选择分区类型'] }]);
        return;
      }

      const _names = [];
      (row.keys||[]).forEach(item => {
        if ((item.name||'')!=='') {
          _names.push(item.name);
        }
      })

      if ((_names||[]).length === 0) {
        form.setFields([{ name: 'keys', errors: ['必须选择字段'] }]);
        return;
      }


      const newData = {
        partitionType: row.type,
        keys: row.keys
      }
  
      onChange && onChange(newData, true);

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

  const onValuesChange = (changedValues, allValues) => {
    // console.log('changed values', changedValues);
    // console.log('all values', allValues);
  };

  const columns = [
    {
      title: '序号',
      dataIndex: 'key',
      editable: false,
      width: 60,
      render: (_, __, index) => {
        return (index+1).toString();
      }
    },
    {
      title: '分区类型',
      width: 200,
      dataIndex: 'type', //注意 这里type改成partitionType会崩溃 暂不清楚是什么问题
      editable: true,
      ellipsis: true,
      render: (text, record, index) => {
        return (
          <Tooltip title={text||''}>
          <span style={{ fontWeight: 'bold' }} >{highlightSearchContentByTerms(record?.partitionType?.name, terms)}</span>
          </Tooltip>
        )
      }
    },
    {
      title: '分区字段列表',
      dataIndex: 'keys',
      editable: true,
      ellipsis: true,
      render: (_, record, index) => {

        return (
          <div>
          {
            (record.keys||[]).map((item, index) => {
              return (
                <Row key={index}>
                  <span>字段: </span>
                  { highlightSearchContentByTerms(item.name||'', terms) }
                </Row>
              )
            })
          }
          </div>
        );
      }
    },
  ];

  const editableColumn = [
    ...columns,
    {
      title: '操作',
      dataIndex: 'action',
      width: 180,
      render: (_, record) => {
        if (!editable) return null;

        return isEditing ? (
          <>
            <Typography.Link className='mr-3' onClick={() => save()}>
              保存
            </Typography.Link>
            <Typography.Link onClick={() => {cancel()}}>
              取消
            </Typography.Link>
            </>
        ) : (
          <>
            <Typography.Link className='mr-3' onClick={() => edit(record)}>
              编辑
            </Typography.Link>
            <Typography.Link className='mr-3' onClick={() => remove(record)}>
              删除
            </Typography.Link>
          </>
        );
      },
    },
  ]

  const mergedColumns = () => {

    if (editable) {

      return editableColumn.map((col) => {
        if (!col.editable) {
          return col;
        }
    
        return {
          ...col,
          onCell: (record) => ({
            record,
            dataIndex: col.dataIndex,
            inputType:  (col.dataIndex==='unique') ? 'check' : 'text',
            colTitle: col.title,
            editing: isEditing,
            attributes,
            partitionTypes: supportedPartitionTypes,
          }),
        };
      });
    }

    return columns;
  }

  let disableAdd = false, addTip = '';
  if (isEditing) {
    disableAdd = true;
    addTip = '正在编辑中,不允许新建';
  } else if (data) {
    disableAdd = true;
    addTip = '已存在分区,不允许再新建';
  }

  return (
    <div className='model-import-action-index'>
      <div className='d-flex mb-3' style={{ justifyContent: 'space-between' }}>
        <h2 style={{ marginBottom: 0 }}>数据表分区</h2> 
        {
          editable && <Tooltip title={addTip}>
            <Button onClick={onAddClick} disabled={disableAdd} >新建</Button>
          </Tooltip>
        }
      </div>
      <div className='mb-3' id="containerId">
        <Form form={form} component={false} onValuesChange={onValuesChange}>
          <Table
            components={{
              body: {
                cell: EditableCell,
                row: null,
              },
            }}
            dataSource={data?[data]:[]}
            columns={mergedColumns()}
            size='small'
            rowClassName="editable-row"
            pagination={false}
            sticky
          />
        </Form>
      </div>
    </div>
  );
};

export default ImportActionPartition;