'use client';
import { useTableState, Column } from '@react-stately/table';
export { Cell, Row, TableBody, TableHeader } from '@react-stately/table';
import { useRef } from 'react';
import { useFocusRing } from '@react-aria/focus';
import { useHover } from '@react-aria/interactions';
import { useTable, useTableRowGroup, useTableHeaderRow, useTableColumnHeader, useTableRow, useTableCell, useTableSelectionCheckbox, useTableSelectAllCheckbox } from '@react-aria/table';
import { mergeProps } from '@react-aria/utils';
import { Checkbox } from '@keystar/ui/checkbox';
import { Text } from '@keystar/ui/typography';
import { toDataAttributes, isReactText } from '@keystar/ui/utils';
import { arrowUpIcon } from '@keystar/ui/icon/icons/arrowUpIcon';
import { Icon } from '@keystar/ui/icon';
import { tokenSchema, css, transition, useStyleProps, classNames } from '@keystar/ui/style';
import { jsx, jsxs } from 'react/jsx-runtime';

// ============================================================================
// UTILS
// ============================================================================

function getStyleFromColumn(props) {
  const {
    maxWidth,
    minWidth,
    width
  } = props;
  if (width) {
    return {
      flex: '0 0 auto',
      width,
      maxWidth,
      minWidth
    };
  }
  return {
    maxWidth,
    minWidth
  };
}

// ============================================================================
// COMPONENTS
// ============================================================================

const SortIndicator = () => {
  // fix alignment: reduce the space the icon takes up, w/o affecting the icon layout itself
  let labelHeight = tokenSchema.typography.text.regular.capheight;
  return /*#__PURE__*/jsx("span", {
    "aria-hidden": "true",
    className: css({
      alignItems: 'center',
      display: 'flex',
      flexShrink: 0,
      height: labelHeight,
      justifyContent: 'center',
      marginInline: tokenSchema.size.space.small,
      opacity: 0,
      position: 'relative',
      transition: transition(['opacity', 'transform'], {
        easing: 'easeOut'
      }),
      width: labelHeight,
      svg: {
        position: 'absolute'
      },
      ['[aria-sort="ascending"] &, [aria-sort="descending"] &']: {
        opacity: 1
      },
      ['[aria-sort="descending"] &']: {
        transform: 'rotate(180deg)'
      }
    }),
    children: /*#__PURE__*/jsx(Icon, {
      src: arrowUpIcon
    })
  });
};

// ============================================================================
// HOOKS
// ============================================================================

// Table root
// ----------------------------------------------------------------------------

function useTableStyleProps(props) {
  let styleProps = useStyleProps(props);
  return {
    ...toDataAttributes(props, new Set(['density', 'overflowMode', 'prominence'])),
    className: classNames(styleProps.className, 'ksv-table-view', css({
      display: 'flex',
      flexDirection: 'column',
      minHeight: 0,
      minWidth: 0
    })),
    style: styleProps.style
  };
}

// Row group (head/body/foot)
// ----------------------------------------------------------------------------

function useHeadStyleProps() {
  return {
    className: css({
      display: 'flex',
      flexDirection: 'column',
      '.ksv-table-view[data-prominence="low"] &': {
        borderBottom: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.muted}`
      }
    })
  };
}
function useBodyStyleProps() {
  return {
    className: css({
      display: 'flex',
      flexDirection: 'column',
      overflow: 'auto',
      '.ksv-table-view:not([data-prominence="low"]) &': {
        backgroundColor: tokenSchema.color.background.canvas,
        border: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.muted}`,
        borderRadius: tokenSchema.size.radius.medium
      }
    })
  };
}

// Cell common
// ----------------------------------------------------------------------------

const commonCellStyles = {
  // borderBottom: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.neutral}`,
  boxSizing: 'border-box',
  cursor: 'default',
  display: 'flex',
  flex: 1,
  justifyContent: 'flex-start',
  minWidth: 0,
  outline: 0,
  paddingInline: tokenSchema.size.space.medium,
  position: 'relative'
};
function useCellStyleProps(props, state) {
  const className = css([commonCellStyles, {
    // Alignment
    '&[data-align="end"]': {
      justifyContent: 'flex-end'
    },
    '&[data-align="center"]': {
      justifyContent: 'center'
    },
    // wrapping text shouldn't be centered
    alignItems: 'center',
    '.ksv-table-view[data-overflow-mode="wrap"] &': {
      alignItems: 'initial'
    },
    // Density
    paddingBlock: tokenSchema.size.space.medium,
    '.ksv-table-view[data-density="compact"] &': {
      paddingBlock: tokenSchema.size.space.regular
    },
    '.ksv-table-view[data-density="spacious"] &': {
      paddingBlock: tokenSchema.size.space.large
    },
    // focus ring
    '&[data-focus="visible"]::after': {
      borderRadius: tokenSchema.size.radius.small,
      boxShadow: `inset 0 0 0 ${tokenSchema.size.alias.focusRing} ${tokenSchema.color.alias.focusRing}`,
      content: '""',
      inset: 0,
      position: 'absolute',
      transition: transition(['box-shadow', 'margin'], {
        easing: 'easeOut'
      })
    },
    // HEADERS
    '&[role="columnheader"]': {
      color: tokenSchema.color.foreground.neutralSecondary,
      ['&[aria-sort]']: {
        cursor: 'default',
        '&:hover, &[data-focus="visible"]': {
          color: tokenSchema.color.foreground.neutralEmphasis
        }
      }
    }
  }]);
  return {
    ...toDataAttributes({
      focus: state !== null && state !== void 0 && state.isFocusVisible ? 'visible' : undefined,
      align: props === null || props === void 0 ? void 0 : props.align
    }),
    className,
    style: getStyleFromColumn(props)
  };
}
function useSelectionCellStyleProps() {
  return {
    className: css(commonCellStyles, {
      alignItems: 'center',
      flex: '0 0 auto',
      paddingInlineStart: tokenSchema.size.space.medium,
      width: 'auto'
    })
  };
}

// Row body
// ----------------------------------------------------------------------------

function useRowStyleProps(state) {
  let calculatedRadius = `calc(${tokenSchema.size.radius.medium} - ${tokenSchema.size.border.regular})`;
  const className = css({
    boxSizing: 'border-box',
    display: 'flex',
    position: 'relative',
    outline: 0,
    '&:not(:last-child)': {
      borderBottom: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.muted}`
    },
    // prominence
    '.ksv-table-view:not([data-prominence="low"]) &': {
      '&:first-child': {
        borderStartStartRadius: calculatedRadius,
        borderStartEndRadius: calculatedRadius
      },
      '&:last-child': {
        borderEndStartRadius: calculatedRadius,
        borderEndEndRadius: calculatedRadius
      }
    },
    // interactions
    '&[data-interaction="hover"]': {
      backgroundColor: tokenSchema.color.alias.backgroundIdle
    },
    '&[data-interaction="press"]': {
      backgroundColor: tokenSchema.color.alias.backgroundHovered
    },
    // focus indicator
    '&[data-focus="visible"]': {
      '&::before': {
        backgroundColor: tokenSchema.color.background.accentEmphasis,
        borderRadius: tokenSchema.size.space.small,
        content: '""',
        insetInlineStart: tokenSchema.size.space.xsmall,
        marginBlock: tokenSchema.size.space.xsmall,
        marginInlineEnd: `calc(${tokenSchema.size.space.small} * -1)`,
        position: 'sticky',
        width: tokenSchema.size.space.small
      }
    },
    // selected
    '&[aria-selected="true"]': {
      backgroundColor: tokenSchema.color.alias.backgroundSelected,
      // boxShadow: `0 0 0 ${tokenSchema.size.border.regular} ${tokenSchema.color.alias.focusRing}`,

      '&[data-interaction="hover"]': {
        backgroundColor: tokenSchema.color.alias.backgroundSelectedHovered
      }
    }
  });
  return {
    ...toDataAttributes({
      focus: state.isFocusVisible ? 'visible' : state.isFocusWithin ? 'within' : undefined,
      interaction: state.isPressed ? 'press' : state.isHovered ? 'hover' : undefined
    }),
    className
  };
}

// Row header
// ----------------------------------------------------------------------------

function useRowHeaderStyleProps() {
  const className = css({
    display: 'flex'
  });
  return {
    className
  };
}

function TableView(props) {
  let ref = useRef(null);
  // @ts-ignore FIXME: Resolve the disparity between the types of TableView and useTableState.
  let state = useTableState({
    ...props,
    showSelectionCheckboxes: props.selectionMode === 'multiple'
  });
  let {
    collection
  } = state;
  let {
    gridProps
  } = useTable(props, state, ref);
  let styleProps = useTableStyleProps(props);
  let rows = [...collection.body.childNodes];
  return /*#__PURE__*/jsxs("div", {
    ...gridProps,
    ...styleProps,
    ref: ref,
    children: [/*#__PURE__*/jsx(TableHead, {
      children: collection.headerRows.map(headerRow => /*#__PURE__*/jsx(TableHeaderRow, {
        item: headerRow,
        state: state,
        children: [...headerRow.childNodes].map(column => column.props.isSelectionCell ? /*#__PURE__*/jsx(TableSelectAllCell, {
          column: column,
          state: state
        }, column.key) : /*#__PURE__*/jsx(TableColumnHeader, {
          column: column,
          state: state
        }, column.key))
      }, headerRow.key))
    }), /*#__PURE__*/jsx(TableBody, {
      children: !rows.length && props.renderEmptyState ? /*#__PURE__*/jsx("div", {
        role: "row",
        "aria-rowindex": 2,
        children: /*#__PURE__*/jsx("div", {
          role: "rowheader",
          "aria-colspan": collection.columnCount,
          children: props.renderEmptyState()
        })
      }) : rows.map(row => /*#__PURE__*/jsx(TableRow, {
        item: row,
        state: state,
        hasAction: !!props.onRowAction,
        children: [...row.childNodes].map(cell => cell.props.isSelectionCell ? /*#__PURE__*/jsx(TableCheckboxCell, {
          cell: cell,
          state: state
        }, cell.key) : /*#__PURE__*/jsx(TableCell, {
          cell: cell,
          state: state,
          overflowMode: props.overflowMode
        }, cell.key))
      }, row.key))
    })]
  });
}

// Styled components
// ------------------------------

function TableHead(_ref) {
  let {
    children
  } = _ref;
  let {
    rowGroupProps
  } = useTableRowGroup();
  let styleProps = useHeadStyleProps();
  return /*#__PURE__*/jsx("div", {
    ...rowGroupProps,
    ...styleProps,
    children: children
  });
}
function TableBody(_ref2) {
  let {
    children
  } = _ref2;
  let {
    rowGroupProps
  } = useTableRowGroup();
  let styleProps = useBodyStyleProps();
  return /*#__PURE__*/jsx("div", {
    ...rowGroupProps,
    ...styleProps,
    children: children
  });
}
function TableHeaderRow(_ref3) {
  let {
    item,
    state,
    children
  } = _ref3;
  let ref = useRef(null);
  let {
    rowProps
  } = useTableHeaderRow({
    node: item
  }, state, ref);
  let styleProps = useRowHeaderStyleProps();
  return /*#__PURE__*/jsx("div", {
    ...rowProps,
    ...styleProps,
    ref: ref,
    children: children
  });
}
function TableColumnHeader(_ref4) {
  let {
    column,
    state
  } = _ref4;
  let ref = useRef(null);
  let {
    columnHeaderProps
  } = useTableColumnHeader({
    node: column
  }, state, ref);
  let {
    isFocusVisible,
    focusProps
  } = useFocusRing();
  let columnProps = column.props;
  let cellStyleProps = useCellStyleProps(columnProps, {
    isFocusVisible
  });
  return /*#__PURE__*/jsxs("div", {
    ...mergeProps(columnHeaderProps, focusProps),
    ...cellStyleProps,
    ref: ref,
    children: [columnProps.allowsSorting && columnProps.align === 'end' && /*#__PURE__*/jsx(SortIndicator, {}), isReactText(column.rendered) ? /*#__PURE__*/jsx(Text, {
      color: "inherit",
      weight: "semibold",
      truncate: true,
      children: column.rendered
    }) : column.rendered, columnProps.allowsSorting && columnProps.align !== 'end' && /*#__PURE__*/jsx(SortIndicator, {})]
  });
}
function TableRow(_ref5) {
  let {
    item,
    children,
    state,
    hasAction
  } = _ref5;
  let ref = useRef(null);
  let allowsInteraction = state.selectionManager.selectionMode !== 'none' || hasAction;
  let isDisabled = !allowsInteraction || state.disabledKeys.has(item.key);
  let {
    rowProps,
    isPressed
  } = useTableRow({
    node: item
  }, state, ref);
  // The row should show the focus background style when any cell inside it is focused.
  // If the row itself is focused, then it should have a blue focus indicator on the left.
  let {
    isFocusVisible: isFocusWithin,
    focusProps: focusWithinProps
  } = useFocusRing({
    within: true
  });
  let {
    isFocusVisible,
    focusProps
  } = useFocusRing();
  let {
    hoverProps,
    isHovered
  } = useHover({
    isDisabled
  });
  let styleProps = useRowStyleProps({
    isFocusVisible,
    isFocusWithin,
    isHovered,
    isPressed
  });
  return /*#__PURE__*/jsx("div", {
    ...mergeProps(rowProps, focusWithinProps, focusProps, hoverProps),
    ...styleProps,
    ref: ref,
    children: children
  });
}
function TableCell(_ref6) {
  let {
    cell,
    overflowMode,
    state
  } = _ref6;
  let ref = useRef(null);
  let {
    gridCellProps
  } = useTableCell({
    node: cell
  }, state, ref);
  let {
    isFocusVisible,
    focusProps
  } = useFocusRing();
  let styleProps = useCellStyleProps(cell.column.props, {
    isFocusVisible
  });
  return /*#__PURE__*/jsx("div", {
    ...mergeProps(gridCellProps, focusProps),
    ...styleProps,
    ref: ref,
    children: isReactText(cell.rendered) ? /*#__PURE__*/jsx(Text, {
      truncate: overflowMode === 'truncate',
      children: cell.rendered
    }) : cell.rendered
  });
}
function TableCheckboxCell(_ref7) {
  let {
    cell,
    state
  } = _ref7;
  let ref = useRef(null);
  let {
    gridCellProps
  } = useTableCell({
    node: cell
  }, state, ref);
  let {
    checkboxProps
  } = useTableSelectionCheckbox({
    key: cell.parentKey
  }, state);
  let styleProps = useSelectionCellStyleProps();
  return /*#__PURE__*/jsx("div", {
    ...styleProps,
    ...gridCellProps,
    ref: ref,
    children: /*#__PURE__*/jsx(Checkbox, {
      ...checkboxProps
    })
  });
}
function TableSelectAllCell(_ref8) {
  let {
    column,
    state
  } = _ref8;
  let ref = useRef(null);
  let {
    columnHeaderProps
  } = useTableColumnHeader({
    node: column
  }, state, ref);
  let {
    checkboxProps
  } = useTableSelectAllCheckbox(state);
  let styleProps = useSelectionCellStyleProps();
  return /*#__PURE__*/jsx("div", {
    ...styleProps,
    ...columnHeaderProps,
    ref: ref,
    children: state.selectionManager.selectionMode === 'single' ? /*#__PURE__*/jsx(Text, {
      visuallyHidden: true,
      children: checkboxProps['aria-label']
    }) : /*#__PURE__*/jsx(Checkbox, {
      ...checkboxProps
    })
  });
}

// Override TS for Column to support Keystar UI specific props.
const VoussoirColumn = Column;

export { VoussoirColumn as Column, TableView };
