import React, { useEffect, useState, useRef, useContext } from 'react';
import {
  CreateTablePost,
  getTableInfo,
  updateTablePost,
  GetDefaultTableFields,
} from '@/services/tablemanager/tablemanager';
import {
  Form,
  Modal,
  Button,
  Input,
  Select,
  Checkbox,
  Table,
  notification,
  InputNumber,
  Tooltip,
  Switch,
  Spin,
} from 'antd';
import {
  DeleteOutlined,
  PlusOutlined,
  MinusOutlined,
  DeleteFilled,
  KeyOutlined,
} from '@ant-design/icons';
import styles from './TableView.less';
import primaryKey from '../../../../../assets/images/icons/主键.svg';
import index from '../../../../../assets/images/icons/索引.svg';
// import { defaultFields } from './defaultFields';
const EditableContext = React.createContext(null);

const tableMap = {
  事件表: '事件',
  事件工单表: '事件',
  工单表: '工单',
  台账表: '台账',
  设备表: '设备',
  反馈表: '反馈',
};
const EditableRow = ({ index, ...props }) => {
  const [form] = Form.useForm();
  return (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...props} />
      </EditableContext.Provider>
    </Form>
  );
};
const EditableCell = ({
  index,
  title,
  editable,
  children,
  dataIndex,
  record,
  handleSave,
  ellipsis,
  width,
  dataSource,
  tableDataCount,
  defaultData,
  ...restProps
}) => {
  const [editing, setEditing] = useState(false);
  const inputRef = useRef(null);
  const form = useContext(EditableContext);

  // 复选框回显
  useEffect(() => {
    if (record && dataIndex === 'IsNullable') {
      form.setFieldsValue({
        [dataIndex]: record[dataIndex],
      });
    }
    if (record && dataIndex === 'IsAddFieldConfig') {
      form.setFieldsValue({
        [dataIndex]: record[dataIndex],
      });
    }
  }, []);

  useEffect(() => {
    if (editing && inputRef.current) {
      inputRef.current.focus();
    }
  }, [editing]);

  const toggleEdit = () => {
    setEditing(!editing);
    form.setFieldsValue({
      [dataIndex]: record[dataIndex],
    });
  };

  const save = async () => {
    try {
      const values = await form.validateFields();
      toggleEdit();
      handleSave({ ...record, [dataIndex]: values[dataIndex], index, errors: [] }, dataIndex);
    } catch (errInfo) {
      toggleEdit();
      handleSave({ ...record, index, errors: errInfo.errorFields[0].errors }, dataIndex);
      console.log('Save failed:', errInfo);
    }
  };
  const saveCheckBox = async () => {
    const values = await form.validateFields();
    form.setFieldsValue({
      [dataIndex]: values.IsNullable,
    });
    handleSave({ ...record, ...values, index });
  };

  const saveAddCheckBox = async e => {
    const values = await form.validateFields();
    form.setFieldsValue({
      [dataIndex]: values.IsAddFieldConfig,
    });
    handleSave({ ...record, ...values, index });
  };

  const rendeFrom = val => {
    let lengthMin = 0;
    let lengthMax = 0;
    let decimalPlaceMin = 0;
    let decimalPlaceMax = 0;
    // 字段类型为精确数值型（decimal），字段长度1-38小数点位数0-38
    if (record.FieldType === 8) {
      lengthMin = 1;
      lengthMax = 38;
      decimalPlaceMin = 0;
      decimalPlaceMax = 38;
    }
    // 字段类型为字符串型（nvarchar）、二进制（varbinary），字段长度为0-4000
    if (record.FieldType === 2 || record.FieldType === 10) {
      lengthMin = 1;
      lengthMax = 4000;
    }
    // 字段类型为字符串型（varchar）、，字段长度为0-8000
    if (record.FieldType === 0 || record.FieldType === 1) {
      lengthMin = 1;
      lengthMax = 8000;
    }
    if (val === '字段名称') {
      return <Input ref={inputRef} onPressEnter={save} onBlur={save} />;
    }
    if (val === '字段类型') {
      return (
        <Select
          ref={inputRef}
          onPressEnter={save}
          onBlur={save}
          showSearch
          filterOption={(input, option) =>
            option.children.toLowerCase().includes(input.toLowerCase())
          }
        >
          <Select.Option value={0}>字符串型（varchar）</Select.Option>
          <Select.Option value={12}>字符串型（varchar(max)）</Select.Option>
          <Select.Option value={1}>字符型（nchar）</Select.Option>
          <Select.Option value={2}>字符串型（nvarchar）</Select.Option>
          <Select.Option value={3}>字符串型（nvarchar(max)）</Select.Option>
          <Select.Option value={4}>布尔型（bit）</Select.Option>
          <Select.Option value={5}>整数型（int）</Select.Option>
          <Select.Option value={6}>浮点型（float）</Select.Option>
          <Select.Option value={7}>长整型（bigint）</Select.Option>
          <Select.Option value={8}>精确数值型（decimal）</Select.Option>
          <Select.Option value={9}>时间（datetime）</Select.Option>
          <Select.Option value={10}>二进制（varbinary）</Select.Option>
          <Select.Option value={11}>二进制（varbinary(max)）</Select.Option>
        </Select>
      );
    }
    if (val === '字段长度') {
      return (
        <InputNumber
          ref={inputRef}
          min={lengthMin}
          max={lengthMax}
          onPressEnter={save}
          onBlur={save}
        />
      );
    }
    if (val === '小数点位') {
      return (
        <InputNumber
          ref={inputRef}
          min={decimalPlaceMin}
          max={decimalPlaceMax}
          onPressEnter={save}
          onBlur={save}
        />
      );
    }

    return <Input ref={inputRef} onPressEnter={save} onBlur={save} />;
  };

  let childNode = children;

  if (editable) {
    // 字段类型为 字符串型（varchar）、二进制（varbinary）、字符型（nchar）、字符串型（nvarchar）、精确数值型（decimal）让修改
    if (
      title === '字段长度' &&
      (record.FieldType !== 0 &&
        record.FieldType !== 10 &&
        record.FieldType !== 1 &&
        record.FieldType !== 2 &&
        record.FieldType !== 8)
    ) {
      return <td {...restProps}>--</td>;
    }
    // 字段类型为 精确数值型（decimal）让修改
    if (title === '小数点位' && record.FieldType !== 8) {
      return <td {...restProps}>--</td>;
    }
    // 只读
    if (record.ReadOnly && title !== '允许空值' && title !== '是否附加') {
      return <td {...restProps}>{childNode}</td>;
    }
    // 表单规则
    let rules = [];
    if (title === '字段名称') {
      rules = [
        {
          required: true,
          message: '字段名称不能为空',
        },
        {
          validator: (rule, value) => {
            let list = JSON.parse(JSON.stringify(dataSource));
            // 合并内置字段
            if (
              value &&
              [...defaultData, ...list].some(
                (item, i) => item.Name === value && item.keyIndex !== record.keyIndex,
              )
            ) {
              return Promise.reject(new Error('字段名称重复，请重新输入'));
            }
            return Promise.resolve();
          },
        },
        {
          pattern: /^(?!(\d+)$)[\u4e00-\u9fffa-zA-Z0-9_]+$/,
          message: '不能输入特殊符号或者纯数字',
        },
      ];
    }
    childNode = editing ? (
      <Form.Item
        style={{
          width: `${width - 20}px`,
          height: '32px',
          margin: 0,
          marginLeft: '50%',
          transform: 'translateX(-50%)',
        }}
        rules={rules}
        name={dataIndex}
      >
        {rendeFrom(title)}
      </Form.Item>
    ) : (
      <div
        className="editable-cell-value-wrap"
        // title={children[1]}
        style={{
          width: `${width - 20}px`,
          height: '32px',
          overflow: 'hidden',
          whiteSpace: 'nowrap',
          textOverflow: 'ellipsis',
          margin: 'auto',
        }}
        onClick={toggleEdit}
      >
        {children}
      </div>
    );
    if (title === '允许空值') {
      childNode = (
        <Form.Item
          style={{
            margin: 0,
          }}
          name={dataIndex}
          valuePropName="checked"
        >
          <Checkbox onChange={saveCheckBox} disabled={record.ReadOnly || tableDataCount} />
        </Form.Item>
      );
    }
    if (title === '是否附加') {
      childNode = (
        <Form.Item
          style={{
            margin: 0,
          }}
          name={dataIndex}
          valuePropName={record.IsAddFieldConfig ? 'checked' : ''}
        >
          <Checkbox onChange={saveAddCheckBox} />
        </Form.Item>
      );
    }
  }

  return <td {...restProps}>{childNode}</td>;
};
const TableView = props => {
  const { callBackSubmit, onCancel, visible, type, formObj, tableType, defaultFieldsList } = props;
  const [dataSource, setDataSource] = useState([]);
  const [count, setCount] = useState(0);
  const [loading, setLoading] = useState(false);
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
  const [tableMsg, setTableMsg] = useState({});
  const [tableDataCount, setTableDataCount] = useState(false);
  const [defaultData, setDefaultData] = useState([]);
  const [showDefault, setShowDefault] = useState(true);
  const [form] = Form.useForm();

  useEffect(() => {
    if (visible) {
      if (type === 'tableEdit') {
        setLoading(true);
        form.setFieldsValue({
          tableName: formObj.tableName,
          alias: formObj.tableAlias,
        });
        getTableInfo({ tableName: formObj.tableName, isIncludeField: true })
          .then(res => {
            setLoading(false);
            if (res.code === 0) {
              setTableDataCount(res.data.root[0].TableDataCount);
              setTableMsg({
                tableStyle: res.data.root[0].tableStyle ? res.data.root[0].tableStyle : '大',
                officeTmpl: res.data.root[0].officeTmpl,
                interfaceName: res.data.root[0].interfaceText,
                tableID: res.data.root[0].tableID,
              });
              const defaultList = [];
              const fieldList = res.data.root[0].TableFields.map((item, index) => {
                const obj = {
                  ...item,
                  keyIndex: index,
                };
                if (item.ReadOnly) {
                  defaultList.push(obj);
                }
                return obj;
              });
              setDefaultData(defaultList);
              setCount(fieldList.length);

              setShowDefault(false);
              let list = JSON.parse(JSON.stringify(fieldList));
              list = list.filter(item => !item.ReadOnly);
              setDataSource(list);
            } else {
              notification.error({ message: '提示', duration: 3, description: res.msg });
            }
          })
          .catch(() => {
            setLoading(false);
            notification.error({ message: '提示', duration: 3, description: '网络异常' });
          });
      } else {
        let list = defaultFieldsList
          .find(item => item.value === tableType)
          .list.map((item, i) => ({ ...item, keyIndex: i }));
        console.log(list);
        setDefaultData(list);
        setCount(list.length);
        setShowDefault(false);
        let listitem = JSON.parse(JSON.stringify(list));
        listitem = listitem.filter(item => !item.ReadOnly);
        setDataSource(listitem);
      }
    } else {
      setShowDefault(false);
      setDataSource([]);
      setDefaultData([]);
      setSelectedRowKeys([]);
      form.resetFields();
    }
  }, [visible]);

  // 提交表单
  const onFinish = () => {
    // 校验提示
    let checkMsg = '';
    let TableFields = JSON.parse(JSON.stringify(dataSource));

    TableFields.forEach((item, index) => {
      item.Order = index;
      if (!item.Name) {
        item.errors = ['字段名称不能为空'];
      }
      if (item.errors?.length > 0) {
        item.errors.forEach(ele => {
          checkMsg = `${checkMsg}第${index + 1}行 校验错误：${ele}\n`;
        });
      }
    });
    if (!showDefault) {
      // 默认字段不显示时要拼接上默认字段
      TableFields = [...defaultData, ...TableFields];
    }
    // if (checkMsg) {
    //   notification.error({
    //     message: '提示',
    //     duration: 3,
    //     description: checkMsg,
    //     style: { whiteSpace: 'pre-wrap' },
    //   });
    //   return;
    // }
    form.validateFields().then(validate => {
      if (validate) {
        if (!validate.tableName) {
          notification.error({ message: '提示', duration: 3, description: '请填写表名' });
          return;
        }

        if (type === 'add') {
          // 新建表
          CreateTablePost({
            ...validate,
            tableName: `${tableType.substr(0, tableType.length - 1)}_${validate.tableName}`,
            TableFields,
            tableType,
            tableStyle: '大',
          }).then(res => {
            if (res.code === 0) {
              notification.success({
                message: '提示',
                duration: 3,
                description: '新增成功',
              });
              callBackSubmit();
            } else {
              notification.error({ message: '提示', duration: 3, description: res.msg });
            }
          });
        } else {
          // 编辑表
          updateTablePost({ ...validate, TableFields, ...tableMsg }).then(res => {
            if (res.code === 0) {
              notification.success({
                message: '提示',
                duration: 3,
                description: '编辑成功',
              });
              callBackSubmit();
            } else {
              notification.error({ message: '提示', duration: 3, description: res.msg });
            }
          });
        }
      }
    });
  };
  // 添加字段
  const handleAdd = () => {
    const newData = {
      keyIndex: count,
      Name: '',
      FieldType: 0,
      FieldLength: 255,
      DecimalPlace: 0,
      IsNullable: true,
      IsAddFieldConfig: true,
    };
    setDataSource([...dataSource, newData]);
    setCount(count + 1);
    setTimeout(() => {
      let tableEl = document.querySelector(`.${styles.content} .ant-table-body`);
      tableEl.scrollTop = tableEl.scrollHeight;
    }, 10);
  };

  // 批量删除字段
  const deleteFilleds = () => {
    if (selectedRowKeys.length === 0) {
      notification.error({ message: '提示', duration: 3, description: '请选择字段' });
      return;
    }
    const list = [];
    dataSource.forEach(item => {
      const isDelete = selectedRowKeys.some(value => value === item.keyIndex);
      if (!isDelete) {
        list.push(item);
      }
    });
    setDataSource(list);
  };
  // 删除字段
  const handleDelete = (record, keyIndex) => {
    if (record.ReadOnly) {
      notification.error({ message: '提示', duration: 3, description: '内置字段不允许删除' });
      return;
    }
    const newData = dataSource.filter((item, index) => index !== keyIndex);
    setDataSource(newData);
  };
  // 修改后存值
  const handleSave = (row, key) => {
    if (key === 'FieldType') {
      if (row.FieldType === 0 || row.FieldType === 2) {
        row.FieldLength = 255;
        row.DecimalPlace = 0;
      } else if (row.FieldType === 10) {
        row.FieldLength = 50;
        row.DecimalPlace = 0;
      } else if (row.FieldType === 1) {
        row.FieldLength = 10;
        row.DecimalPlace = 0;
      } else if (row.FieldType === 8) {
        row.FieldLength = 18;
        row.DecimalPlace = 3;
      } else {
        row.FieldLength = 0;
        row.DecimalPlace = 0;
      }
    }
    const { index } = row;
    const newData = [...dataSource];
    const item = newData[index];
    newData.splice(index, 1, { ...item, ...row });
    setDataSource(newData);
  };
  // 是否显示默认字段
  const showDefaultFields = e => {
    setShowDefault(e);
    let list = JSON.parse(JSON.stringify(dataSource));
    if (e) {
      // 显示内置字段
      list = [...defaultData, ...list];
    } else {
      list = list.filter(item => !item.ReadOnly);
    }
    setDataSource(list);
  };
  // 表格设置
  const components = {
    body: {
      row: EditableRow,
      cell: EditableCell,
    },
  };
  const defaultColumns = [
    {
      title: '序号',
      align: 'center',
      width: 50,
      render: (text, record, index) => <span>{index + 1}</span>,
    },
    {
      title: '字段名称',
      dataIndex: 'Name',
      width: 200,
      // ellipsis: true,
      editable: true,
      align: 'center',
      render: (text, record) => (
        <>
          <span>{text}</span>
          {record.IsIndex && (
            <img src={index} style={{ height: '25px', marginLeft: '5px' }} alt="" />
          )}
          {record.IsPrimaryKey && (
            <img src={primaryKey} style={{ height: '25px', marginLeft: '5px' }} alt="" />
          )}
        </>
      ),
    },
    {
      title: '字段类型',
      dataIndex: 'FieldType',
      width: 220,
      ellipsis: true,
      editable: true,
      align: 'center',
      render: text => {
        switch (text) {
          case 0:
            return '字符串型（varchar）';
          case 1:
            return '字符型（nchar）';
          case 2:
            return '字符串型（nvarchar）';
          case 3:
            return '字符串型（nvarchar(max)）';
          case 4:
            return '布尔型（bit）';
          case 5:
            return '整数型（int）';
          case 6:
            return '浮点型（float）';
          case 7:
            return '长整型（bigint）';
          case 8:
            return '精确数值型（decimal）';
          case 9:
            return '时间（datetime）';
          case 10:
            return '二进制（varbinary）';
          case 11:
            return '二进制（varbinary(max)）';
          case 12:
            return '字符串型（varchar(max)）';

          default:
            return null;
        }
      },
    },
    {
      title: '字段长度',
      dataIndex: 'FieldLength',
      width: 100,
      ellipsis: true,
      editable: true,
      align: 'center',
    },
    {
      title: '小数点位',
      dataIndex: 'DecimalPlace',
      width: 100,
      ellipsis: true,
      editable: true,
      align: 'center',
    },
    {
      title: '允许空值',
      dataIndex: 'IsNullable',
      width: 100,
      editable: true,
      align: 'center',
    },
    {
      title: '是否附加',
      dataIndex: 'IsAddFieldConfig',
      width: 100,
      editable: true,
      align: 'center',
    },
    {
      title: '操作',
      width: 100,
      align: 'center',
      render: (_, record, index) =>
        dataSource.length >= 1 ? (
          <Tooltip title="删除">
            <DeleteOutlined
              onClick={() => handleDelete(record, index)}
              style={{ fontSize: '16px', color: `${record.ReadOnly ? '#ccc' : '#e86060'}` }}
            />
          </Tooltip>
        ) : null,
    },
  ];
  const columns = defaultColumns.map(col => {
    if (!col.editable) {
      return col;
    }
    return {
      ...col,
      onCell: (record, index) => ({
        index,
        record,
        editable: col.editable,
        dataIndex: col.dataIndex,
        width: col.width,
        title: col.title,
        ellipsis: col.ellipsis,
        align: col.align,
        dataSource,
        tableDataCount,
        defaultData,
        handleSave,
      }),
    };
  });
  // 表格复选框
  const onSelectChange = newSelectedRowKeys => {
    setSelectedRowKeys(newSelectedRowKeys);
  };
  const rowSelection = {
    selectedRowKeys,
    onChange: onSelectChange,
    getCheckboxProps: record => ({
      disabled: record.ReadOnly,
    }),
  };
  return (
    <Modal
      title={type === 'add' ? `建表【${tableType}】` : `表编辑`}
      visible={visible}
      width="1300px"
      onOk={onFinish}
      onCancel={onCancel}
      maskClosable={false}
      destroyOnClose
      centered
    >
      <div className={styles.content}>
        <Form form={form}>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <div style={{ display: 'flex' }}>
              <Form.Item
                label="表名"
                rules={[
                  {
                    required: true,
                    message: '表名称不能为空',
                  },
                  {
                    pattern: /^[\u4e00-\u9fffa-zA-Z0-9_]+$/,
                    message: '不能输入特殊符号',
                  },
                ]}
                name="tableName"
                required
                style={{ marginBottom: '0' }}
              >
                <Input
                  addonBefore={
                    type === 'add' ? `${tableType.substr(0, tableType.length - 1)}_` : null
                  }
                  placeholder="请填写表名"
                />
              </Form.Item>
              <Form.Item
                label="别名"
                name="alias"
                style={{ marginBottom: '0', marginLeft: '10px' }}
              >
                <Input placeholder="请填写别名" />
              </Form.Item>
            </div>
            <div style={{ display: 'flex' }}>
              <Form.Item label="内置字段" style={{ marginBottom: '0', marginRight: '10px' }}>
                <Switch
                  checkedChildren="显示"
                  unCheckedChildren="隐藏"
                  onChange={showDefaultFields}
                />
              </Form.Item>
              <Form.Item style={{ marginBottom: '0', marginRight: '10px' }}>
                <Button type="primary" onClick={() => handleAdd()}>
                  <div style={{ display: 'flex', alignItems: 'center' }}>
                    <PlusOutlined style={{ marginRight: '5px' }} />
                    <span> 新增</span>
                  </div>
                </Button>
              </Form.Item>
              <Form.Item style={{ marginBottom: '0' }}>
                <Button onClick={() => deleteFilleds()}>
                  <div style={{ display: 'flex', alignItems: 'center' }}>
                    <MinusOutlined style={{ marginRight: '5px' }} />
                    <span> 批量删除</span>
                  </div>
                </Button>
              </Form.Item>
            </div>
          </div>
        </Form>
        <Spin spinning={loading}>
          <Table
            rowKey="keyIndex"
            rowSelection={rowSelection}
            size="small"
            style={{ marginTop: '10PX' }}
            components={components}
            rowClassName={() => 'editable-row'}
            bordered
            dataSource={dataSource}
            columns={columns}
            scroll={{ y: '540px' }}
            pagination={false}
            id="box"
          />
          <div id="page-bottom" />
        </Spin>
      </div>
    </Modal>
  );
};
export default TableView;
