/*
  *  自定义浏览框组件
  *   弹框选择
  * @Author:    黎永顺
  * @Date:      2024/8/30
  * @Wechat:
  * @Email:     971387674@qq.com
  * @description:
*/
import React, { Component } from "react";
import { WeaDialog, WeaInputSearch, WeaLocaleProvider, WeaNewScroll, WeaTable, WeaTransfer } from "ecCom";
import { Button, Col, Row, Spin } from "antd";
import CustomBrowserMutiLeft from "./customBrowserMutiLeft";
import CustomBrowserMutiRight from "./customBrowserMutiRight";
import CustomBrowserOperation from "./customBrowserOperation";
import { postFetch } from "../../../util/request";

const WeaTransferList = WeaTransfer.list;
const getLabel = WeaLocaleProvider.getLabel;

class CustomBrowserDialog extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false, listDatas: [], pageInfo: { current: 1, pageSize: 10, total: 0 }, selectedRowKeys: [],
      query: { [props.searchParamsKey]: "" }, singleFilterVal: "",
      leftListSelectedKeys: [], // 左侧table选择的keys
      leftListSelectedData: [], // 左侧table选择的数据
      rightCheckedKeys: [], //右侧选择的keys
      rightDatas: []  // 右侧展示的数据
    };
    this.selectedData = {};
  }

  componentWillReceiveProps(nextProps, nextContext) {
    if (nextProps.visible !== this.props.visible && nextProps.visible) {
      this.getData();
      this.setState({
        selectedRowKeys: nextProps.selectedValues,
        leftListSelectedData: _.values(nextProps.datas), rightDatas: _.values(nextProps.datas)
      });
    } else {
      this.setState({
        pageInfo: { current: 1, pageSize: 10, total: 0 }, query: { [this.props.searchParamsKey]: "" },
        rightDatas: [], rightCheckedKeys: [], leftListSelectedData: [], leftListSelectedKeys: []
      });
      this.selectedData = {};
    }
  }

  getData = () => {
    const { pageInfo, query } = this.state;
    const { dialogType, completeURL, convertDatasource, dataParams = {} } = this.props;
    let payload = { ...dataParams, ...query };
    dialogType === "table" && (payload = { ...pageInfo, ...payload, ...query });
    this.setState({ loading: true });
    postFetch(completeURL, payload).then(({ status, data }) => {
      this.setState({ loading: false });
      if (status && data.list) {
        const { pageNum: current, pageSize, total } = data;
        this.setState({
          listDatas: convertDatasource ? convertDatasource(data.list) : data.list,
          pageInfo: { ...pageInfo, current, pageSize, total }
        });
      } else {
        this.setState({ listDatas: _.map(data, o => ({ ...o, id: String(o.id) })) });
      }
    });
  };
  handleRowClick = record => {
    if (!this.props.isSingle) return;
    const values = [record.id];
    const selectedData = { [record["id"]]: record };
    this.props.onCancel();
    this.props.onChange && this.props.onChange(values, selectedData);
  };
  handleClear = () => {
    this.props.onCancel();
    this.props.onChange && this.props.onChange([], {});
  };
  handleOk = () => {
    const { selectedRowKeys, rightDatas } = this.state, { dialogType } = this.props;
    const convertSelectedRowKeys = dialogType !== "table" ? rightDatas.map((v) => v.id) : selectedRowKeys;
    convertSelectedRowKeys.forEach((v) => {
      let item = this.getItemById(v);
      if (item) this.selectedData[v] = item;
    });
    this.props.onChange && this.props.onChange(convertSelectedRowKeys, this.selectedData);
    this.props.onCancel && this.props.onCancel();
  };
  getItemById = (id) => {
    const { listDatas } = this.state;
    if (this.selectedData[id]) return this.selectedData[id];
    if (!_.isEmpty(listDatas)) {
      for (let i = 0; i < listDatas.length; i++) {
        if (String(id) === String(listDatas[i].id)) return listDatas[i];
      }
    }
  };
  onLeftListCheck = (keys, datas) => {
    const { leftListSelectedData } = this.state;
    let targets = leftListSelectedData.concat(datas);
    targets = _.uniqBy(targets, "id");
    targets = targets.filter((t) => keys.indexOf(t["id"]) > -1);
    this.setState({ leftListSelectedKeys: keys, leftListSelectedData: targets });
  };
  onleftDoubleClick = (data) => {
    const { rightDatas } = this.state;
    this.setState({
      rightDatas: rightDatas.concat(data),
      rightCheckedKeys: [],
      leftListSelectedData: [],
      leftListSelectedKeys: []
    });
  };
  onRightDoubleClick = (key) => {
    const { rightDatas } = this.state;
    const newRightDatas = rightDatas.filter(item => String(item.id) !== key);
    this.setState({ rightDatas: newRightDatas, rightCheckedKeys: [] });
  };
  moveTo = (direction) => {
    const { rightDatas, rightCheckedKeys, listDatas, leftListSelectedData } = this.state;
    if (direction === "right") {
      this.setState({
        rightDatas: rightDatas.concat(leftListSelectedData),
        leftListSelectedData: [],
        leftListSelectedKeys: []
      });
    } else if (direction === "left") {
      this.setState({
        rightDatas: rightDatas.filter(item => !rightCheckedKeys.some(checkedKey => String(item.id) === checkedKey)),
        rightCheckedKeys: []
      });
    } else if (direction === "allToLeft") {
      this.setState({ rightDatas: [], rightCheckedKeys: [] });
    } else if (direction === "allToRight") {
      if (this.leftListAllActive()) {
        this.setState({
          rightDatas: rightDatas.concat(listDatas),
          rightCheckedKeys: [],
          leftListSelectedData: [],
          leftListSelectedKeys: []
        });
      }
    }
  };
  leftListAllActive = () => {
    const { rightDatas, listDatas } = this.state;
    let bool = true;
    if (_.isEmpty(listDatas)) bool = false;
    if (!_.isEmpty(listDatas) && !_.isEmpty(rightDatas)) {
      bool = listDatas.filter((l) => !rightDatas.some(r => l.id === r.id)).length !== 0;
    }
    return bool;
  };
  renderTitle = () => {
    const { dialogType, searchParamsKey, isSingle } = this.props, {
      query, pageInfo, selectedRowKeys, singleFilterVal
    } = this.state;
    return (<div className="wea-hr-muti-dialog-title">
      <span>{getLabel(111, "数据选择")}</span>
      {
        dialogType === "table" ?
          <WeaInputSearch
            value={query[searchParamsKey]} style={{ width: 220 }}
            onChange={value => this.setState({ query: { ...query, [searchParamsKey]: value } })}
            onSearch={() => {
              this.setState({ pageInfo: { ...pageInfo, current: 1 } }, () => {
                this.getData();
                selectedRowKeys.forEach((v) => {
                  let item = this.getItemById(v);
                  if (item) this.selectedData[v] = item;
                });
              });
            }}/> : isSingle ?
            <WeaInputSearch value={singleFilterVal} onChange={singleFilterVal => this.setState({ singleFilterVal })}/> :
            <div/>
      }
    </div>);
  };

  render() {
    const {
      loading, listDatas, pageInfo, selectedRowKeys, query, leftListSelectedKeys, rightDatas, rightCheckedKeys,
      singleFilterVal
    } = this.state;
    const { dialogType, tableProps: { rowKey, columns }, isSingle, searchParamsKey } = this.props;
    const sheight = this.dialog ? this.dialog.state.height - 116 : 260;
    const buttons = [
      <Button type="primary" onClick={this.handleOk}
              disabled={dialogType !== "table" && _.isEmpty(rightDatas)}>{getLabel(111, "确 定")}</Button>,
      <Button type="ghost" onClick={this.handleClear}>{getLabel(111, "清 除")}</Button>,
      <Button type="ghost" onClick={this.props.onCancel}>{getLabel(111, "取 消")}</Button>];
    let rightActive = false, leftActive = false, rightAllActive = false;
    if (leftListSelectedKeys && leftListSelectedKeys.length > 0) rightActive = true;
    if (rightCheckedKeys && rightCheckedKeys.length > 0) leftActive = true;
    if (rightDatas && rightDatas.length > 0) rightAllActive = true;
    let dom = <Spin spinning={loading}>
      <div className="wea-hr-muti-dialog">
        {
          !isSingle ? <React.Fragment>
              <div className="wea-hr-muti-input-left">
                <Row style={{ height: 35 }}>
                  <Col span="24">
                    <WeaInputSearch value={query[searchParamsKey]} onSearch={this.getData}
                                    onChange={value => this.setState({ query: { ...query, [searchParamsKey]: value } })}
                    />
                  </Col>
                </Row>
                <div>
                  <WeaNewScroll height={this.dialog ? this.dialog.state.height - 51 : 260}>
                    <CustomBrowserMutiLeft
                      filterData={rightDatas}
                      datas={listDatas}
                      onDoubleClick={this.onleftDoubleClick}
                      onClick={this.onLeftListCheck}
                      selectedKeys={leftListSelectedKeys}
                    />
                  </WeaNewScroll>
                </div>
              </div>
              <div className="wea-transfer-opration">
                <CustomBrowserOperation
                  rightActive={rightActive}
                  leftActive={leftActive}
                  leftAllActive={this.leftListAllActive()}
                  rightAllActive={rightAllActive}
                  moveToRight={() => this.moveTo("right")}
                  moveToLeft={() => this.moveTo("left")}
                  moveAllToRight={() => this.moveTo("allToRight")}
                  moveAllToLeft={() => this.moveTo("allToLeft")}
                />
              </div>
              <div className="wea-hr-muti-input-right">
                <CustomBrowserMutiRight
                  height={this.dialog ? this.dialog.state.height - 51 : 260}
                  data={rightDatas} checkedKeys={rightCheckedKeys}
                  checkedCb={rightCheckedKeys => this.setState({ rightCheckedKeys })}
                  onDoubleClick={this.onRightDoubleClick}
                />
              </div>
            </React.Fragment> :
            <WeaTransferList height={this.dialog ? this.dialog.state.height - 16 : 260} checkedKeys={[]}
                             checkedCb={([id]) => this.handleRowClick(_.find(listDatas, item => item.id === id))}
                             data={listDatas.filter((item) => item.name.indexOf(_.trim(singleFilterVal)) > -1)}/>
        }
      </div>
    </Spin>;
    if (dialogType === "table") {
      const pagination = {
        ...pageInfo,
        showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
        showQuickJumper: true,
        showSizeChanger: true,
        pageSizeOptions: ["10", "20", "50", "100"],
        onShowSizeChange: (current, pageSize) => {
          this.setState({
            pageInfo: { ...pageInfo, current, pageSize }
          }, () => {
            this.getData();
            selectedRowKeys.forEach((v) => {
              let item = this.getItemById(v);
              if (item) this.selectedData[v] = item;
            });
          });
        },
        onChange: current => {
          this.setState({ pageInfo: { ...pageInfo, current } }, () => {
            this.getData();
            selectedRowKeys.forEach((v) => {
              let item = this.getItemById(v);
              if (item) this.selectedData[v] = item;
            });
          });
        }
      };
      const rowSelection = {
        selectedRowKeys,
        onChange: selectedRowKeys => this.setState({ selectedRowKeys })
      };
      dom = <div className="wea-hr-muti-input-table">
        <WeaTable dataSource={listDatas} loading={loading} pagination={pagination} scroll={{ y: sheight }}
                  onRowClick={this.handleRowClick} rowSelection={!isSingle ? rowSelection : null}
                  rowKey={rowKey || "id"} columns={columns}/>
      </div>;
    }
    dialogType === "table" && isSingle && buttons.splice(0, 1);
    return (
      <WeaDialog
        {...this.props} initLoadCss ref={dom => this.dialog = dom} title={this.renderTitle()}
        className="custom_browser_dialog" draggable={false} style={{
        width: 784, height: 460, minHeight: 200, minWidth: 380,
        maxHeight: "90%", maxWidth: "90%", overflow: "hidden", transform: "translate(0px, 0px)"
      }} buttons={buttons}>{dom}</WeaDialog>
    );
  }
}

export default CustomBrowserDialog;
