import React, { memo, useMemo, Fragment } from 'react';
import classNames from 'classnames';
import { groupBy as groupByUtil } from '@pisell/utils';
import PisellBasicGrid from "../PisellBasicGrid";
import { COMPONENT_PREFIX, getGroupFieldNames, resolveItemKey } from "./utils";
import "./PisellGroupView.less";

/**
 * 将 ItemLayout 对象布局映射为 PisellBasicGrid 的方向/换行属性
 */
var mapBasicGridDirection = function mapBasicGridDirection(direction) {
  return direction === 'vertical' ? 'vertical' : 'horizontal';
};

/**
 * PisellGroupView 分组展示组件
 * @template T - 数据项类型
 * @description
 * 通用、数据无关的「分组展示容器」：先按 `groupBy` 将 `dataSource` 分组，
 * 再为每个分组渲染头部 / 统计 / 主体 / 操作四块。各块均可由外部自定义渲染，
 * 组件本身不耦合任何业务字段语义。
 *
 * @example
 * <PisellGroupView
 *   dataSource={bookings}
 *   groupBy={['productId', 'time']}
 *   renderHeader={(g) => <div>{g.keyMap.productId} · {g.keyMap.time}</div>}
 *   renderStats={(g) => <div>共 {g.items.length} 项</div>}
 *   renderItem={(item) => <BookingItem dataSource={item} />}
 *   renderActions={(g) => <button>批量编辑</button>}
 * />
 */
var PisellGroupView = function PisellGroupView(props) {
  var _renderEmpty;
  var dataSource = props.dataSource,
    groupBy = props.groupBy,
    getGroupId = props.getGroupId,
    sortGroups = props.sortGroups,
    sortItems = props.sortItems,
    renderHeader = props.renderHeader,
    renderStats = props.renderStats,
    renderItem = props.renderItem,
    renderActions = props.renderActions,
    _props$itemLayout = props.itemLayout,
    itemLayout = _props$itemLayout === void 0 ? 'stack' : _props$itemLayout,
    renderBody = props.renderBody,
    renderGroup = props.renderGroup,
    renderEmpty = props.renderEmpty,
    rowKey = props.rowKey,
    _props$variant = props.variant,
    variant = _props$variant === void 0 ? 'desktop' : _props$variant,
    className = props.className,
    style = props.style;

  /**
   * 参与分组的字段名，透传给 renderItem 供调用方过滤头部已展示字段
   */
  var groupFieldNames = useMemo(function () {
    return getGroupFieldNames(groupBy);
  }, [groupBy]);

  /**
   * 分组结果
   */
  var groups = useMemo(function () {
    return groupByUtil(dataSource || [], groupBy, {
      getGroupId: getGroupId,
      sortGroups: sortGroups,
      sortItems: sortItems
    });
  }, [dataSource, groupBy, getGroupId, sortGroups, sortItems]);

  /**
   * 渲染单个分组的主体（第三块）
   */
  var renderDefaultBody = function renderDefaultBody(group) {
    var _layout$wrap;
    if (!renderItem) {
      return null;
    }
    var itemNodes = group.items.map(function (item, index) {
      return /*#__PURE__*/React.createElement(Fragment, {
        key: resolveItemKey(item, index, rowKey)
      }, renderItem(item, {
        group: group,
        index: index,
        groupKeys: groupFieldNames
      }));
    });

    // 'stack' 直接纵向堆叠
    if (itemLayout === 'stack') {
      return /*#__PURE__*/React.createElement("div", {
        className: "".concat(COMPONENT_PREFIX, "__body-stack")
      }, itemNodes);
    }

    // 对象布局透传给 PisellBasicGrid
    var layout = itemLayout;
    return /*#__PURE__*/React.createElement(PisellBasicGrid, {
      direction: mapBasicGridDirection(layout.direction),
      wrap: (_layout$wrap = layout.wrap) !== null && _layout$wrap !== void 0 ? _layout$wrap : 'wrap',
      columns: layout.columns,
      gap: layout.gap
    }, itemNodes);
  };

  /**
   * 渲染单个分组
   */
  var renderSingleGroup = function renderSingleGroup(group) {
    var _renderHeader, _renderStats, _renderActions;
    var headerNode = (_renderHeader = renderHeader === null || renderHeader === void 0 ? void 0 : renderHeader(group)) !== null && _renderHeader !== void 0 ? _renderHeader : null;
    var statsNode = (_renderStats = renderStats === null || renderStats === void 0 ? void 0 : renderStats(group)) !== null && _renderStats !== void 0 ? _renderStats : null;
    var defaultBody = renderDefaultBody(group);
    var bodyNode = renderBody ? renderBody(group, defaultBody) : defaultBody;
    var actionsNode = (_renderActions = renderActions === null || renderActions === void 0 ? void 0 : renderActions(group)) !== null && _renderActions !== void 0 ? _renderActions : null;

    // 完全自定义整组容器
    if (renderGroup) {
      var blocks = {
        header: headerNode,
        stats: statsNode,
        body: bodyNode,
        actions: actionsNode
      };
      return /*#__PURE__*/React.createElement(Fragment, {
        key: group.groupId
      }, renderGroup(group, blocks));
    }
    return /*#__PURE__*/React.createElement("div", {
      key: group.groupId,
      className: "".concat(COMPONENT_PREFIX, "__group")
    }, headerNode !== null && /*#__PURE__*/React.createElement("div", {
      className: "".concat(COMPONENT_PREFIX, "__header")
    }, headerNode), statsNode !== null && /*#__PURE__*/React.createElement("div", {
      className: "".concat(COMPONENT_PREFIX, "__stats")
    }, statsNode), bodyNode !== null && bodyNode !== undefined && /*#__PURE__*/React.createElement("div", {
      className: "".concat(COMPONENT_PREFIX, "__body")
    }, bodyNode), actionsNode !== null && /*#__PURE__*/React.createElement("div", {
      className: "".concat(COMPONENT_PREFIX, "__actions")
    }, actionsNode));
  };
  var isEmpty = groups.length === 0;
  return /*#__PURE__*/React.createElement("div", {
    className: classNames(COMPONENT_PREFIX, "".concat(COMPONENT_PREFIX, "--").concat(variant), className),
    style: style
  }, isEmpty ? (_renderEmpty = renderEmpty === null || renderEmpty === void 0 ? void 0 : renderEmpty()) !== null && _renderEmpty !== void 0 ? _renderEmpty : null : groups.map(renderSingleGroup));
};

/**
 * 使用 memo 优化性能：props 未变化时跳过重渲染
 */
var MemoizedPisellGroupView = /*#__PURE__*/memo(PisellGroupView);
export { MemoizedPisellGroupView as PisellGroupView };
export default MemoizedPisellGroupView;