import React, { useEffect, useState, useRef, useContext, useMemo } from 'react';
import {
  CreateTablePost,
  getTableInfo,
  updateTablePost,
  GetDefaultTableFields,
  reloadTableFields,
  removeFields,
} from '@/services/tablemanager/tablemanager';
import {
  Form,
  Modal,
  Button,
  Input,
  Select,
  Checkbox,
  Table,
  notification,
  InputNumber,
  Tooltip,
  Switch,
  Spin,
  Empty,
} 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 clearImg from '@/assets/font/omsfont/clear.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="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 [exceptionArr, setExceptionArr] = useState([]);
  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);
      }
      reloadTableFieldsArr();
    } else {
      setShowDefault(false);
      setDataSource([]);
      setDefaultData([]);
      setSelectedRowKeys([]);
      setExceptionArr([]);
      form.resetFields();
    }
  }, [visible]);

  const removeMissingFields = () => {
    let ids = exceptionArr.map(item => item.ID).join(',');
    removeFields({
      fieldIDs: ids,
    }).then(res => {
      if (res.code === 0) {
        notification.success({
          message: '提示',
          duration: 3,
          description: '清除成功',
        });
        reloadTableFieldsArr();
      }
    });
  };
  const reloadTableFieldsArr = () => {
    reloadTableFields({
      tableName: formObj.tableName,
    }).then(res => {
      if (res.msg === 'Ok') {
        setExceptionArr(res.data.root.filter(item => item.group === '(缺少字段)'));
      }
    });
  };

  // 提交表单
  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 addArr = useMemo(() => {
    let arr = JSON.parse(JSON.stringify(dataSource));
    if (showDefault) {
      return arr;
    }
    return [...defaultData, ...arr];
  }, [showDefault, defaultData, dataSource]);
  // 修改后存值
  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 });
    // 内置字段同步更改
    // if (index < defaultData.length) {
    //   const newDefaultData = [...defaultData];
    //   newDefaultData.splice(index, 1, { ...item, ...row });
    //   setDefaultData(newDefaultData);
    // }
    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 deleteAddField = (index, name) => {
    let arr = JSON.parse(JSON.stringify(dataSource));
    arr.forEach(item => {
      if (item.Name === name) {
        item.IsAddFieldConfig = false;
      }
    });
    console.log(arr, name, 'arrarrarrarrarrarr');
    setDataSource(arr);
  };
  // 表格设置
  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: 50,
      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}>
        <div>
          <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>
        <div className={styles.subContent}>
          <div className={styles.subArea} style={{ height: exceptionArr.length ? '70%' : '100%' }}>
            <div className={styles.subTitle}>已附加字段集</div>
            <div className={styles.subItems}>
              {addArr.map((item, index) =>
                item.IsAddFieldConfig ? (
                  <div className={styles.subItem}>
                    <span>{item.Alias || item.Name}</span>{' '}
                    <span
                      className={styles.deleteItem}
                      onClick={() => deleteAddField(index, item.Name)}
                    >
                      X
                    </span>
                  </div>
                ) : null,
              )}
              {/* {dataSource.some(item => {
                item.IsAddFieldConfig;
              })?:<Empty
              image={Empty.PRESENTED_IMAGE_SIMPLE}
              description="暂无数据"
              style={{ margin: '20px auto 0px auto', paddingTop: '50px' }}
            />} */}
            </div>
          </div>
          {exceptionArr.length ? (
            <div className={styles.exceptionArea}>
              <div className={styles.subTitle}>
                异常字段集{' '}
                <Button
                  danger
                  style={{
                    borderRadius: '4px',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'space-around',
                  }}
                  onClick={() => removeMissingFields()}
                  size="small"
                >
                  <img src={clearImg} alt="" style={{ width: '14px' }} />
                  一键清除
                </Button>
              </div>
              <div className={styles.subItems}>
                {exceptionArr.map((item, index) => (
                  <div className={styles.subItem}>
                    <span style={{ color: 'red' }}>{item.alias || item.name}</span>{' '}
                  </div>
                ))}
              </div>
            </div>
          ) : null}
        </div>
      </div>
    </Modal>
  );
};
export default TableView;