import * as React from 'react';
import { createTable } from '../table-core/index';
//
/**
 * If rendering headers, cells, or footers with custom markup, use flexRender instead of `cell.getValue()` or `cell.renderValue()`.
 */
export function flexRender(Comp, props) {
    return !Comp ? null : isReactComponent(Comp) ? React.createElement(Comp, { ...props }) : Comp;
}
function isReactComponent(component) {
    return (isClassComponent(component) || typeof component === 'function' || isExoticComponent(component));
}
function isClassComponent(component) {
    return (typeof component === 'function' &&
        (() => {
            const proto = Object.getPrototypeOf(component);
            return proto.prototype && proto.prototype.isReactComponent;
        })());
}
function isExoticComponent(component) {
    return (typeof component === 'object' &&
        typeof component.$$typeof === 'symbol' &&
        ['react.memo', 'react.forward_ref'].includes(component.$$typeof.description));
}
export function useReactTable(options) {
    // Compose in the generic options to the user options
    const resolvedOptions = {
        state: {}, // Dummy state
        onStateChange: () => { }, // noop
        renderFallbackValue: null,
        ...options,
    };
    // Create a new table and store it in state
    const [tableRef] = React.useState(() => ({
        current: createTable(resolvedOptions),
    }));
    // By default, manage table state here using the table's initial state
    const [state, setState] = React.useState(() => tableRef.current.initialState);
    // Compose the default state above with any user state. This will allow the user
    // to only control a subset of the state if desired.
    tableRef.current.setOptions((prev) => ({
        ...prev,
        ...options,
        state: {
            ...state,
            ...options.state,
        },
        // Similarly, we'll maintain both our internal state and any user-provided
        // state.
        onStateChange: (updater) => {
            var _a;
            setState(updater);
            (_a = options.onStateChange) === null || _a === void 0 ? void 0 : _a.call(options, updater);
        },
    }));
    return tableRef.current;
}
