import React from "react";
import * as XLSX from "xlsx";
import {Button, Dialog, Checkbox, Icon, Overlay} from "@alifd/next";
import {event} from "@alilc/lowcode-engine";

import {HotTable} from "@handsontable/react";
import "handsontable/dist/handsontable.full.min.css";

interface EXCELSetterProps {
  value: object[];
  onChange: (val: object[]) => void;
  field: any;
}

export default class EXCELSetter extends React.PureComponent<
  EXCELSetterProps,
  any
> {
  static displayName = "EXCELSetter";
  state = {
    visible: false,
    showNotice: false,
    data: [],
    columnHeaders: [],
    selectedCol: [],
    savedData: [],
  };

  hotRef = React.createRef<any>();
  fileRef = React.createRef<any>();

  onOpen = () => {
    this.setState({visible: true, showNotice: false});
    this.readInData(this.props.value);
  };

  onClose = () => {
    this.setState({visible: false});
  };

  onConfirm = () => {
    const {onChange, field} = this.props;
    const options: any[] = [];
    this.state.selectedCol.forEach((e) => {
      options.push({label: e, value: e});
    });
    field.parent.setPropValue("fieldOptions", options);
    event.emit("FieldsMapping");
    onChange(this.state.savedData);
    this.setState({visible: false});
  };

  fileChange = (e: any) => {
    let file = e.target?.files[0];
    if (!file) {
      return;
    }
    let endName = file.name.split(".")[1];
    if (endName !== "xls" && endName !== "xlsx") {
      alert("导入的文件格式不正确!");
      return;
    }
    const reader = new FileReader();
    reader.onload = (readerEvent) => {
      let finalData = XLSX.read(readerEvent.target?.result, {
        type: "binary",
      });
      // 这是每个Sheet的名字。
      let SheetNames = finalData.SheetNames;
      // 这是每页的数据内容。
      let Sheets = finalData.Sheets;
      // 调用方法转为json
      let result = XLSX.utils.sheet_to_json(Sheets[SheetNames[0]], {
        header: 1,
      });
      this.setState({data: result.slice(1), columnHeaders: result[0]});
    };
    reader.readAsArrayBuffer(file);
    this.setState({selectedCol: []});
  };

  readInData = (val: object[]) => {
    const res = [];
    if (val.length > 0) {
      res.push(Object.keys(val[0]));
      val?.forEach((e) => {
        if (!e) {
          return;
        }
        res.push(Object.values(e));
      });
      this.setState({
        data: res.slice(1),
        columnHeaders: res[0],
        selectedCol: [],
      });
      return res;
    }
  };

  saveData = (selectedCol: any[]) => {
    const res: any[] = [];
    const hotInstance = this.hotRef.current?.hotInstance;
    const {columnHeaders} = this.state;

    const length = hotInstance.countRows() ?? 0;
    if (length <= 0) {
      return;
    }

    for (let i = 0; i < length; i++) {
      const rowData = hotInstance.getDataAtRow(i);

      const rowObj = {};
      selectedCol?.forEach((e) => {
        const index = columnHeaders.indexOf(e);
        rowObj[e] = rowData[index];
      });
      res.push(rowObj);
    }
    this.setState({savedData: res});
  };

  noEmptyJug = () => {
    if (this.state.selectedCol.length > 0) {
      return true;
    } else {
      this.setState({showNotice: true});
    }
  };

  renderNotice() {
    if (this.state.showNotice) {
      return (
        <div
          style={{
            color: "red",
            fontSize: 12,
            margin: "12px 0 0 0",
          }}>
          还没有选择字段！
        </div>
      );
    }
  }

  render() {
    const {Popup} = Overlay;
    return (
      <>
        <Button
          size="small"
          type="primary"
          style={{width: "100%"}}
          onClick={this.onOpen}>
          编辑数据
        </Button>
        <Dialog
          visible={this.state.visible}
          title="编辑数据"
          style={{width: 800}}
          onOk={() => {
            if (this.noEmptyJug()) {
              this.onConfirm();
            }
          }}
          onCancel={this.onClose}
          onClose={this.onClose}>
          <div style={{width: "100%", height: "500px", marginTop: -10}}>
            <Button
              style={{marginRight: 8}}
              onClick={() => {
                this.fileRef.current?.showPicker();
              }}>
              选择文件
            </Button>
            <span>
              仅支持 .xls,.xlsx
              格式，以表格形式展现，请严格按照格式要求上传表格！
            </span>
            <Popup
              triggerType={["hover", "click"]}
              children={
                <img
                  width="660px"
                  style={{
                    backgroundColor: "white",
                    padding: 20,
                    border: " solid 1px",
                  }}
                  src="https://gw.alipayobjects.com/zos/basement_prod/fe4b3cac-c181-4aa8-a267-37b2fea9fe85.svg"
                  alt=""
                />
              }
              trigger={<Icon type="help" size="xs"/>}
              v2
              placement="b"
            />
            <input
              ref={this.fileRef}
              type="file"
              accept=".xlsx,.xls"
              onChange={this.fileChange}
              style={{display: "none"}}
            />
            {this.state.data.length !== 0 ? (
              <div style={{marginTop: 12}}>
                <HotTable
                  ref={this.hotRef}
                  data={this.state.data}
                  width="100%"
                  height={320}
                  colHeaders={this.state.columnHeaders}
                  rowHeaders={true}
                  viewportRowRenderingOffset={100}
                  viewportColumnRenderingOffset={100}
                  colWidths={140}
                  licenseKey="non-commercial-and-evaluation"
                />
                <span
                  style={{display: "block", marginTop: 12, marginBottom: 8}}>
                  选择需要读取的字段：
                </span>
                <Checkbox.Group
                  value={this.state.selectedCol}
                  dataSource={this.state.columnHeaders}
                  onChange={(e) => {
                    this.setState({showNotice: false});
                    this.setState({selectedCol: e});
                    this.saveData(e);
                  }}></Checkbox.Group>
                {this.renderNotice()}
              </div>
            ) : null}
          </div>
        </Dialog>
      </>
    );
  }
}
