import React, { forwardRef, useImperativeHandle, useMemo, useState } from 'react';
import Xspreadsheet from 'modules/Xspreadsheet/xspreadsheet';
import 'modules/Xspreadsheet/index.scss';
import cloneDeep from 'lodash/cloneDeep';
import { mergeData } from './util';
import message from 'components/message';
const faultTolerantLen = 120;

export type EasyvCsvExcelRef = {
  reload: (initData: any) => void;
  getData: () => any;
  getChangedStatus: () => boolean;
};

interface EasyvCsvExcelProps {
  width?: React.CSSProperties['width'];
  height?: React.CSSProperties['height'];
  data?: any[];
  containerId: string;
  contentId: string;
  style?: React.CSSProperties;
  readonly?: boolean;
}

const EasyvCsvExcel = forwardRef<EasyvCsvExcelRef, EasyvCsvExcelProps>((props, ref) => {
  const sheetEl = React.useRef(null);
  const sheetRef = React.useRef<any>(null);
  const [isEdited, setIsEdited] = useState(false);
  const { data, containerId, contentId, height, width, style = { minHeight: 500 }, readonly = false } = props;

  useImperativeHandle(ref, () => ({
    getData: () => {
      const csvData = cloneDeep(sheetRef.current.getData());
      if (Array.isArray(csvData) && csvData.length) {
        const rowsKeys:Set<string> = new Set();
        const rows = csvData[0].rows;
        Object.keys(rows).forEach((item) => {
          if (rows[item]?.cells) {
            Object.keys(rows[item].cells).forEach((i) => {
              if (!rowsKeys.has(i)) {
                rowsKeys.add(i);
              }
            });
          }
        });
        const newData = Object.keys(rows)
          .reduce((pre, cur) => {
            return [...pre, rows[cur]?.cells];
          }, [])
          .map((item) => {
            const keys = Object.keys(item || {});
            return [...rowsKeys].map((cur) => {
              if (keys.includes(cur)) {
                return item[cur].text;
              }
              return '';
            });
          })
          .filter((item) => item.filter((o) => !o).length !== [...rowsKeys].length);
        return newData.length ? newData : [[undefined]];
      }
      return [[undefined]];
    },
    reload: (initData: any) => {
      sheetRef.current.loadData(mergeData(initData));
    },
    getChangedStatus: () => {
      return isEdited;
    }
  }));

  const DOM = useMemo(() => {
    return (
      <div id={containerId} style={style}>
        <div id={contentId} style={{ width: '100%', height: 'inherit' }} ref={sheetEl}>
          {!sheetRef.current ? '初始化...' : null}
        </div>
      </div>
    );
  }, [props.data, height]);

  React.useEffect(() => {
    const element: any = sheetEl.current;
    if (Array.isArray(data)) {
      element.innerHTML = null;
      const sheet = new Xspreadsheet(
        `#${contentId}`,
        {
          mode: readonly ? 'read' : 'edit',
          showGrid: true,
          showContextmenu: !readonly,
          showToolbar: false,
          showBottomBar: false,
          extendToolbar: false,
          view: {
            height: () => {
              return (
                height ||
                document.getElementById(`${containerId}`)?.offsetHeight ||
                document.documentElement.clientHeight - faultTolerantLen
              );
            },
            width: () => {
              return width || document.getElementById(`${containerId}`)?.offsetWidth || document.documentElement.clientWidth;
            }
          },
          col: {
            width: 76,
            indexWidth: 76,
            len: data.length === 0 ? 26 : data[0].length > 26 ? data[0].length : 26
          },
          row: {
            height: 36,
            len: data.length === 0 ? 50 : data.length > 50 ? data.length : 50
          },
          style: {
            bgcolor: '#181A24',
            align: 'center',
            valign: 'middle',
            textwrap: false,
            strike: false,
            underline: false,
            color: '#fff',
            font: {
              name: 'Arial',
              size: 12,
              bold: false,
              italic: false
            },
            format: 'normal'
          }
        },
        message
      ).loadData(mergeData(data)); // load data
      sheet.change(() => {
        setIsEdited(true);
      });
      sheetRef.current = sheet;
    }
    return () => {
      sheetRef.current = null;
      (element as any).innerHTML = '';
    };
  }, [DOM]);

  return <>{DOM}</>;
});
export default EasyvCsvExcel;
