import {
  Table,
  Input,
  Divider,
  Tooltip,
  InputNumber,
  Select,
  Grid,
} from "antd";
import React, { useState, useMemo, useEffect, useRef } from "react";
import AutoTable from "@/components/Tableform/mtable";
import { Scrollbars } from "react-custom-scrollbars";
import { CloseOutlined } from "@ant-design/icons";
import styles from "./index.less";

let { Option } = Select;
const { useBreakpoint } = Grid;

function unique(arr, key) {
  var hash = [];
  for (var i = 0; i < arr.length; i++) {
    let hashlist = hash.length > 0 ? hash.map((it) => it[key]) : [];
    if (arr[i] && hashlist.indexOf(arr[i][key]) == -1) {
      hash.push(arr[i]);
    }
  }
  return hash;
}

const usePrevious = (value) => {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
};

export default function CheckTable({
  value,
  onChange,
  pagination,
  columns,
  extraparams,
  path,
  editable,
  rowKey,
  rowName,
  tabletype = "checkbox",
  dataSource,
  isDisabled,
  actionRef,
}) {
  let [first, cf] = useState(true),
    [currentkey, changecur] = useState(),
    newcolumns = columns,
    [startData, cfs] = useState([]),
    [expandedRows, cexpand] = useState([]),
    [options, setoptions] = useState({});
  const preParams = usePrevious(extraparams);
  const screens = useBreakpoint();
  if (editable) {
    function getval(item, record) {
      let { dataIndex } = item, //修改字段的key
        hasval =
          value && value.length > 0
            ? value.filter((it) => it[rowKey] == record[rowKey])
            : []; //value中是否存在id为当前的值
      if (hasval.length == 0) {
        //不存在
        return record[dataIndex];
      } else {
        //存在
        return hasval[0][dataIndex];
      }
    }
    newcolumns = columns.map((item, i) => {
      let idlist = value ? value.map((it) => it[rowKey]) : [];
      //下拉options定义
      //编辑逻辑
      if (item.selectedRender == "InputNumber") {
        let render = (_, record) => {
          if (idlist.indexOf(record[rowKey]) == -1) {
            return <span>{getval(item, record)}</span>;
          } else {
            return (
              <InputNumber
                min={0}
                value={getval(item, record)}
                onChange={(val) => {
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              ></InputNumber>
            );
          }
        };
        item.render = render;
      } else if (item.selectedRender == "Select") {
        let render = (_, record) => {
          /**
           *
           * renderNull 当前行某一个字段的某种值时，当前单元格渲染为空
           *
           * optionsFields 下拉框的值在当前行数据里面时，optionsFields就是下拉框值在当前行数据中所对应的字段
           */
          if (item.renderNull && Array.isArray(item.renderNull)) {
            let klink = {},
              names = item.renderNull.map((it) => it.name);
            names.map((it) => {
              klink[it] = record[it];
            });
            let requiredlist = item.renderNull.map((it) => {
              if (it.equalvalue) {
                let equalvalue =
                  it.equalvalue &&
                  Array.isArray(it.equalvalue) &&
                  it.equalvalue.length > 0
                    ? it.equalvalue.indexOf(klink[it.name]) != -1
                    : klink[it.name] == it.equalvalue;
                return equalvalue;
              } else if (it.unequalvalue) {
                let unequalvalue =
                  it.unequalvalue &&
                  Array.isArray(it.unequalvalue) &&
                  it.unequalvalue.length > 0
                    ? it.unequalvalue.indexOf(klink[it.name]) == -1
                    : klink[it.name] != it.unequalvalue;
                return unequalvalue;
              } else {
                return true;
              }
            });
            let rq = requiredlist.some((it) => it == true);
            if (rq) {
              return <></>;
            }
          }
          let curselected, alloption;
          if (item.optionsFields) {
            alloption = JSON.parse(
              JSON.stringify(record[item.optionsFields] ?? [])
            );
          } else {
            if (Array.isArray(item.options)) {
            } else {
              curselected = Array.isArray(record[item.dataIndex])
                ? record[item.dataIndex]
                : record[item.dataIndex]
                ? [record[item.dataIndex]]
                : [];
              alloption = unique(
                [...options[item.key], ...curselected],
                "value"
              );
            }
          }
          let resval = getval(item, record);
          if (item.mode == "multiple") {
            return (
              <Select
                disabled={idlist.indexOf(record[rowKey]) == -1}
                mode={item.mode}
                value={
                  resval ? resval.map((it) => (it?.value ? it.value : it)) : []
                }
                onChange={(val) => {
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              >
                {Array.isArray(item.options)
                  ? item.options.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))
                  : alloption.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))}
              </Select>
            );
          } else {
            return (
              <Select
                disabled={idlist.indexOf(record[rowKey]) == -1}
                mode={item.mode}
                value={
                  resval
                    ? Array.isArray(resval)
                      ? resval.map((it) => (it?.value ? it.value : it))[0]
                      : resval
                    : null
                }
                onChange={(val) => {
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              >
                {Array.isArray(item.options)
                  ? item.options.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))
                  : alloption.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))}
              </Select>
            );
          }
        };
        item.render = render;
      } else if (item.selectedRender == "Input") {
        let render = (_, record) => {
          if (idlist.indexOf(record[rowKey]) == -1) {
            return <span>{getval(item, record)}</span>;
          } else {
            return (
              <Input
                value={getval(item, record)}
                onChange={(e) => {
                  let val = e.target.value;
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              ></Input>
            );
          }
        };
        item.render = render;
      }
      return item;
    });
  }

  function getoptions(extraparams) {
    columns.map((item) => {
      if (!Array.isArray(item.options) && item.options) {
        item
          .options(item.params ? item.params : { ...extraparams })
          .then((res) => {
            setoptions((options) => {
              return {
                ...options,
                [item.key]: res.data.dataList,
              };
            });
          });
      }
    });
  }
  useMemo(() => {
    if (
      !extraparams ||
      JSON.stringify(preParams) == JSON.stringify(extraparams)
    ) {
      return;
    }
    onChange([]); //传参改变清空数据
    getoptions(extraparams);
  }, [extraparams]);

  useEffect(() => {
    if (dataSource && !path) {
      cfs(value);
    }
  }, [dataSource]);

  return editable ? (
    <div style={{ border: "#ddd solid 1px" }} className="fatable">
      <AutoTable
        showQuickJumper="false"
        rowKey={rowKey}
        dataSource={!path ? (dataSource ? dataSource : []) : null}
        withCard={false}
        columns={newcolumns}
        pagination={pagination}
        extraparams={extraparams}
        getDefaultSelected={(data) => {
          //查询时的初始化
          cfs(data.selectedList);
          if (data.selectedList && data.selectedList.length > 0 && first) {
            onChange(
              data.selectedList.map((it) => {
                let cir = it;
                for (let i in it) {
                  if (Array.isArray(it[i])) {
                    let ismu = columns.filter((it) => it.dataIndex == i)[0];
                    if (ismu && ismu.mode == "multiple") {
                      cir[i] = it[i].map((item) =>
                        item?.value ? item?.value : item
                      );
                    } else {
                      cir[i] = it[i].map((item) =>
                        item?.value ? item?.value : item
                      )[0];
                    }
                  }
                }
                return cir;
              })
            ); //设置value
            cf(false);
          }
        }}
        path={path}
        rowSelection={{
          selectedRowKeys: value ? value.map((it) => it[rowKey]) : [],
          preserveSelectedRowKeys: true,
          onChange: (selectedRowKeys, expandedRowes) => {
            let conval = value && Array.isArray(value) ? value : [];
            let limits = unique([...conval, ...expandedRowes], rowKey),
              expander = [];
            expander = selectedRowKeys.map((it) => {
              return limits.filter((item) => item[rowKey] == it)[0];
            });
            expander = expander.map((it) => {
              let neit = it;
              Object.keys(options).map((item) => {
                let vals = neit[item];
                if (vals) {
                  if (Array.isArray(vals)) {
                    vals = vals.map((it) => (it?.value ? it.value : it));
                  }
                }
                neit = {
                  ...neit,
                  [item]: vals,
                };
              });
              return neit;
            });
            onChange(expander);
          },
          getCheckboxProps: (record) => ({
            disabled: isDisabled
              ? path
                ? startData?.map((el) => el[rowKey]).indexOf(record[rowKey]) !=
                  -1
                : value?.map((el) => el[rowKey]).indexOf(record[rowKey]) != -1
              : false,
          }),
        }}
        tableRender={(_, dom) => (
          <div
            style={{
              display: "flex",
              width: "100%",
              overflow: "hidden",
            }}
          >
            <div
              style={{
                flex: 1,
              }}
            >
              {dom}
            </div>
            {!isDisabled
              ? value?.length > 0 &&
                Object.values(screens).filter((it) => it === true).length >
                  2 && (
                  <div
                    style={{
                      width: 120,
                      overflow: "hidden",
                      display: "flex",
                      flexDirection: "column",
                    }}
                  >
                    <div
                      style={{
                        padding: "14px 6px",
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                      }}
                    >
                      <span style={{ fontSize: 16 }}>选中：</span>
                      <span style={{ fontSize: 16 }}>{value?.length}个</span>
                    </div>
                    <div style={{ flex: 1, paddingBottom: 18 }}>
                      <Scrollbars
                        thumbMinSize={10}
                        autoHide
                        style={{ width: "100%", height: "100%" }}
                        hideTracksWhenNotNeeded={true}
                      >
                        {value.map((it, i) => {
                          return (
                            <div
                              key={i}
                              className={styles.items}
                              onClick={() => {
                                changecur(it[rowKey]);
                              }}
                            >
                              <Tooltip title={it[rowName] ? it[rowName] : ""}>
                                <i>{it[rowName] ? it[rowName] : ""}</i>
                              </Tooltip>
                              <CloseOutlined
                                onClick={(e) => {
                                  e.stopPropagation();
                                  if (it[rowKey] == currentkey) {
                                    changecur(null);
                                  }
                                  let newexpandedRows = value.filter(
                                    (its) => its[rowKey] != it[rowKey]
                                  );
                                  onChange(newexpandedRows);
                                }}
                              />
                            </div>
                          );
                        })}
                      </Scrollbars>
                    </div>
                  </div>
                )
              : value?.length > 0 &&
                Object.values(screens).filter((it) => it === true).length > 2 &&
                value.filter(
                  (item) =>
                    startData?.map((el) => el[rowKey])?.indexOf(item[rowKey]) ==
                    -1
                )?.length > 0 && (
                  <div
                    style={{
                      width: 120,
                      overflow: "hidden",
                      display: "flex",
                      flexDirection: "column",
                    }}
                  >
                    <div
                      style={{
                        padding: "14px 6px",
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                      }}
                    >
                      <span style={{ fontSize: 16 }}>选中：</span>
                      <span style={{ fontSize: 16 }}>{value?.length}个</span>
                    </div>
                    <div style={{ flex: 1, paddingBottom: 18 }}>
                      <Scrollbars
                        thumbMinSize={10}
                        autoHide
                        style={{ width: "100%", height: "100%" }}
                        hideTracksWhenNotNeeded={true}
                      >
                        {value.map((it, i) => {
                          return (
                            <div
                              key={i}
                              className={styles.items}
                              onClick={() => {
                                changecur(it[rowKey]);
                              }}
                            >
                              <Tooltip title={it[rowName] ? it[rowName] : ""}>
                                <i>{it[rowName] ? it[rowName] : ""}</i>
                              </Tooltip>
                              {startData
                                ?.map((el) => el[rowKey])
                                ?.indexOf(it[rowKey]) == -1 && (
                                <CloseOutlined
                                  onClick={(e) => {
                                    e.stopPropagation();
                                    if (it[rowKey] == currentkey) {
                                      changecur(null);
                                    }
                                    let newexpandedRows = value.filter(
                                      (its) => its[rowKey] != it[rowKey]
                                    );
                                    onChange(newexpandedRows);
                                  }}
                                />
                              )}
                            </div>
                          );
                        })}
                      </Scrollbars>
                    </div>
                  </div>
                )}
          </div>
        )}
        rowClassNameFn={(record, index) => {
          if (currentkey === record[rowKey]) {
            return "selectedRow";
          }
          return null;
        }}
        actionRef={actionRef ?? null}
      ></AutoTable>
    </div>
  ) : (
    <div style={{ border: "#ddd solid 1px" }} className="fatable">
      <AutoTable
        showQuickJumper="false"
        rowKey={rowKey}
        columns={columns}
        dataSource={!path ? (dataSource ? dataSource : []) : null}
        withCard={false}
        pagination={pagination}
        extraparams={extraparams}
        getDefaultSelected={(data) => {
          cfs(data.selectedList);
          if (value && first) {
            cexpand([...expandedRows, ...value]);
            cf(false);
          }
        }}
        path={path}
        rowSelection={
          tabletype != "noSelect"
            ? {
                selectedRowKeys: value
                  ? value.map((it) => {
                      if (typeof it == "object") {
                        return it[rowKey];
                      } else {
                        return it;
                      }
                    })
                  : [],
                preserveSelectedRowKeys: true,
                type: tabletype,
                onChange: (selectedRowKeys, expandedRowes) => {
                  onChange(selectedRowKeys);
                  let limits = unique(
                      [...expandedRows, ...expandedRowes],
                      rowKey
                    ),
                    expander = [];
                  expander = selectedRowKeys.map((it) => {
                    return limits.filter((item) => item[rowKey] == it)[0];
                  });
                  cexpand(expander);
                },
                getCheckboxProps: (record) => ({
                  disabled: isDisabled
                    ? path
                      ? startData
                          ?.map((el) => el[rowKey])
                          .indexOf(record[rowKey]) != -1
                      : value
                          ?.map((el) => el[rowKey])
                          .indexOf(record[rowKey]) != -1
                    : false,
                }),
              }
            : false
        }
        tableRender={(_, dom) => (
          <div
            style={{
              display: "flex",
              width: "100%",
              overflow: "hidden",
            }}
          >
            <div
              style={{
                flex: 1,
              }}
            >
              {dom}
            </div>
            {!isDisabled
              ? value?.length > 0 &&
                Object.values(screens).filter((it) => it === true).length >
                  2 && (
                  <div
                    style={{
                      width: 120,
                      overflow: "hidden",
                      display: "flex",
                      flexDirection: "column",
                    }}
                  >
                    <div
                      style={{
                        padding: "14px 6px",
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                      }}
                    >
                      <span style={{ fontSize: 16 }}>选中：</span>
                      <span style={{ fontSize: 16 }}>{value?.length}个</span>
                    </div>
                    <div style={{ flex: 1, paddingBottom: 18 }}>
                      <Scrollbars
                        thumbMinSize={10}
                        autoHide
                        style={{ width: "100%", height: "100%" }}
                        hideTracksWhenNotNeeded={true}
                      >
                        {expandedRows.map((it) => {
                          return (
                            <div
                              className={styles.items}
                              onClick={() => {
                                changecur(it[rowKey]);
                              }}
                              key={it[rowKey]}
                            >
                              <Tooltip title={it ? it[rowName] : ""}>
                                <i>{it ? it[rowName] : ""}</i>
                              </Tooltip>

                              <CloseOutlined
                                onClick={(e) => {
                                  e.stopPropagation();
                                  if (it[rowKey] == currentkey) {
                                    changecur(null);
                                  }
                                  let newvalues = value.filter(
                                    (item) => item != it[rowKey]
                                  );
                                  onChange(newvalues);
                                  let newexpandedRows = expandedRows.filter(
                                    (its) => its[rowKey] != it[rowKey]
                                  );
                                  cexpand(newexpandedRows);
                                }}
                              />
                            </div>
                          );
                        })}
                      </Scrollbars>
                    </div>
                  </div>
                )
              : value?.length > 0 &&
                Object.values(screens).filter((it) => it === true).length > 2 &&
                value.filter(
                  (item) =>
                    startData?.map((el) => el[rowKey])?.indexOf(item[rowKey]) ==
                    -1
                )?.length > 0 && (
                  <div
                    style={{
                      width: 120,
                      overflow: "hidden",
                      display: "flex",
                      flexDirection: "column",
                    }}
                  >
                    <div
                      style={{
                        padding: "14px 6px",
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                      }}
                    >
                      <span style={{ fontSize: 16 }}>选中：</span>
                      <span style={{ fontSize: 16 }}>{value?.length}个</span>
                    </div>
                    <div style={{ flex: 1, paddingBottom: 18 }}>
                      <Scrollbars
                        thumbMinSize={10}
                        autoHide
                        style={{ width: "100%", height: "100%" }}
                        hideTracksWhenNotNeeded={true}
                      >
                        {expandedRows.map((it) => {
                          return (
                            <div
                              className={styles.items}
                              onClick={() => {
                                changecur(it[rowKey]);
                              }}
                              key={it[rowKey]}
                            >
                              <Tooltip title={it ? it[rowName] : ""}>
                                <i>{it ? it[rowName] : ""}</i>
                              </Tooltip>
                              {startData
                                ?.map((el) => el[rowKey])
                                ?.indexOf(it[rowKey]) == -1 && (
                                <CloseOutlined
                                  onClick={(e) => {
                                    e.stopPropagation();
                                    if (it[rowKey] == currentkey) {
                                      changecur(null);
                                    }
                                    let newvalues = value.filter(
                                      (item) => item != it[rowKey]
                                    );
                                    onChange(newvalues);
                                    let newexpandedRows = expandedRows.filter(
                                      (its) => its[rowKey] != it[rowKey]
                                    );
                                    cexpand(newexpandedRows);
                                  }}
                                />
                              )}
                            </div>
                          );
                        })}
                      </Scrollbars>
                    </div>
                  </div>
                )}
          </div>
        )}
        rowClassNameFn={(record, index) => {
          if (currentkey === record[rowKey]) {
            return "selectedRow";
          }
          return null;
        }}
        actionRef={actionRef ?? null}
      ></AutoTable>
    </div>
  );
}
