import React, { forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import classNames from "classnames";
import Column from "./PickerColumn";
import { Loading } from "../loading";
import useRefs from "../hooks/use-refs";
import { extend, preventDefault, unitToPx } from "../utils";
import { BORDER_UNSET_TOP_BOTTOM } from "../utils/constant";
import ConfigProviderContext from "../config-provider/ConfigProviderContext";
import useEventListener from "../hooks/use-event-listener";
const Picker = /* @__PURE__ */ forwardRef((props, ref) => {
  const {
    prefixCls,
    createNamespace
  } = useContext(ConfigProviderContext);
  const [bem] = createNamespace("picker", prefixCls);
  const [refs, setRefs] = useRefs();
  const [formattedColumns, setFormattedColumns] = useState([]);
  const {
    text: textKey,
    values: valuesKey,
    children: childrenKey
  } = extend({
    text: "text",
    values: "values",
    children: "children"
  }, props.columnsFieldNames);
  const wrapper = useRef(null);
  const itemHeight = useMemo(() => unitToPx(props.itemHeight), [props.itemHeight]);
  const dataType = useMemo(() => {
    const {
      columns
    } = props;
    const firstColumn = columns[0] || {};
    if (typeof firstColumn === "object") {
      if (childrenKey in firstColumn) {
        return "cascade";
      }
      if (valuesKey in firstColumn) {
        return "object";
      }
    }
    return "plain";
  }, [props.columns]);
  const formatCascade = () => {
    var _a;
    const formatted = [];
    let cursor = {
      [childrenKey]: props.columns
    };
    while (cursor && cursor[childrenKey]) {
      const children = cursor[childrenKey];
      let defaultIndex = (_a = cursor.defaultIndex) != null ? _a : +props.defaultIndex;
      while (children[defaultIndex] && children[defaultIndex].disabled) {
        if (defaultIndex < children.length - 1) {
          defaultIndex++;
        } else {
          defaultIndex = 0;
          break;
        }
      }
      formatted.push({
        [valuesKey]: cursor[childrenKey],
        className: cursor.className,
        defaultIndex
      });
      cursor = children[defaultIndex];
    }
    setFormattedColumns(formatted);
  };
  const format = () => {
    const {
      columns
    } = props;
    if (dataType === "plain") {
      setFormattedColumns([{
        [valuesKey]: columns
      }]);
    } else if (dataType === "cascade") {
      formatCascade();
    } else {
      setFormattedColumns(columns);
    }
  };
  const getIndexes = () => refs.map((_ref) => _ref.getIndex());
  const setColumnValues = (index, options) => {
    const column = refs[index];
    if (column) {
      column.setOptions(options);
    }
  };
  const onCascadeChange = (columnIndex) => {
    let cursor = {
      [childrenKey]: props.columns
    };
    const indexes = getIndexes();
    for (let i = 0; i <= columnIndex; i += 1) {
      cursor = cursor[childrenKey][indexes[i]];
    }
    while (cursor && cursor[childrenKey]) {
      columnIndex += 1;
      setColumnValues(columnIndex, cursor[childrenKey]);
      cursor = cursor[childrenKey][cursor.defaultIndex || 0];
    }
  };
  const getChild = (index) => refs[index];
  const getColumnValue = (index) => {
    const column = getChild(index);
    return (column == null ? void 0 : column.getValue()) || void 0;
  };
  const setColumnValue = (index, value) => {
    const column = getChild(index);
    if (column) {
      column.setValue(value);
      if (dataType === "cascade") {
        onCascadeChange(index);
      }
    }
  };
  const getColumnIndex = (index) => {
    const column = getChild(index);
    return (column == null ? void 0 : column.getIndex()) || 0;
  };
  const setColumnIndex = (columnIndex, optionIndex) => {
    const column = getChild(columnIndex);
    if (column) {
      column.setIndex(optionIndex);
      if (dataType === "cascade") {
        onCascadeChange(columnIndex);
      }
    }
  };
  const getColumnValues = (index) => {
    const column = getChild(index);
    return column == null ? void 0 : column.getOptions();
  };
  const getValues = () => refs.map((_ref) => _ref.getValue());
  const setValues = (values) => {
    values.forEach((value, index) => {
      setColumnValue(index, value);
    });
  };
  const setIndexes = (indexes) => {
    indexes.forEach((optionIndex, columnIndex) => {
      setColumnIndex(columnIndex, optionIndex);
    });
  };
  const onChange = (columnIndex) => {
    if (dataType === "cascade") {
      onCascadeChange(columnIndex);
    }
    if (props.onChange) {
      if (dataType === "plain") {
        props.onChange(getColumnValue(0), getColumnIndex(0));
      } else {
        props.onChange(getValues(), columnIndex);
      }
    }
  };
  const confirm = () => {
    if (props.onConfirm) {
      if (dataType === "plain") {
        props.onConfirm(getColumnValue(0), getColumnIndex(0));
      } else {
        props.onConfirm(getValues(), getIndexes());
      }
    }
  };
  const cancel = () => {
    var _a, _b;
    if (dataType === "plain") {
      (_a = props.onCancel) == null ? void 0 : _a.call(props, getColumnValue(0), getColumnIndex(0));
    } else {
      (_b = props.onCancel) == null ? void 0 : _b.call(props, getValues(), getIndexes());
    }
  };
  const renderTitle = () => {
    if (props.title) {
      return /* @__PURE__ */ React.createElement("div", {
        className: classNames(bem("title"), "rc-ellipsis")
      }, props.title);
    }
    return null;
  };
  const renderCancel = () => {
    const text = props.cancelButtonText || "\u53D6\u6D88";
    return /* @__PURE__ */ React.createElement("button", {
      type: "button",
      className: classNames(bem("cancel")),
      onClick: cancel
    }, text);
  };
  const renderConfirm = () => {
    const text = props.confirmButtonText || "\u786E\u8BA4";
    return /* @__PURE__ */ React.createElement("button", {
      type: "button",
      className: classNames(bem("confirm")),
      onClick: confirm
    }, text);
  };
  const renderToolbar = () => {
    return props.showToolbar ? /* @__PURE__ */ React.createElement("div", {
      className: classNames(bem("toolbar"))
    }, props.toolbar || /* @__PURE__ */ React.createElement(React.Fragment, null, renderCancel(), renderTitle(), renderConfirm())) : null;
  };
  const renderColumnItems = () => formattedColumns.map((item, columnIndex) => {
    var _a;
    return /* @__PURE__ */ React.createElement(Column, {
      key: String(columnIndex),
      optionRender: props.optionRender,
      ref: setRefs(columnIndex),
      textKey,
      readonly: props.readonly,
      className: item.className,
      itemHeight,
      defaultIndex: (_a = item.defaultIndex) != null ? _a : +props.defaultIndex,
      swipeDuration: props.swipeDuration,
      visibleItemCount: props.visibleItemCount,
      initialOptions: item[valuesKey],
      onChange: () => {
        onChange(columnIndex);
      }
    });
  });
  const renderColumns = () => {
    const wrapHeight = itemHeight * props.visibleItemCount;
    const frameStyle = {
      height: `${itemHeight}px`
    };
    const columnsStyle = {
      height: `${wrapHeight}px`
    };
    const maskStyle = {
      backgroundSize: `100% ${(wrapHeight - itemHeight) / 2}px`
    };
    return /* @__PURE__ */ React.createElement("div", {
      ref: wrapper,
      className: classNames(bem("columns")),
      style: columnsStyle
    }, renderColumnItems(), /* @__PURE__ */ React.createElement("div", {
      className: classNames(bem("mask")),
      style: maskStyle
    }), /* @__PURE__ */ React.createElement("div", {
      className: classNames(BORDER_UNSET_TOP_BOTTOM, bem("frame")),
      style: frameStyle
    }));
  };
  useEffect(() => {
    format();
  }, [props.columns]);
  useEventListener("touchmove", preventDefault, {
    target: wrapper.current,
    depends: [wrapper.current]
  });
  useImperativeHandle(ref, () => ({
    confirm,
    getValues,
    setValues,
    getIndexes,
    setIndexes,
    getColumnIndex,
    setColumnIndex,
    getColumnValue,
    setColumnValue,
    getColumnValues,
    setColumnValues
  }));
  return /* @__PURE__ */ React.createElement("div", {
    className: classNames(bem(), props.className)
  }, props.toolbarPosition === "top" ? renderToolbar() : null, props.loading ? /* @__PURE__ */ React.createElement(Loading, {
    className: classNames(bem("loading"))
  }) : null, props.columnsTop, renderColumns(), props.columnsBottom, props.toolbarPosition === "bottom" ? renderToolbar() : null);
});
Picker.defaultProps = {
  itemHeight: 44,
  visibleItemCount: 5,
  swipeDuration: 1e3,
  defaultIndex: 0,
  showToolbar: true,
  toolbarPosition: "top"
};
Picker.displayName = "Picker";
var stdin_default = Picker;
export {
  stdin_default as default
};
