"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const React = __importStar(require("react"));
const styled_components_1 = __importDefault(require("styled-components"));
const ErrorFallbackDiv = styled_components_1.default.div `
  backgroundcolor: ghostwhite;
  color: black;
  font-weight: 600;
  display: block;
  padding: 10px;
  margin-bottom: 20px;
`;
const ErrorFallback = (caught) => (React.createElement(ErrorFallbackDiv, null,
    caught.error ? React.createElement("h3", null, caught.error.toString()) : null,
    React.createElement("details", null,
        React.createElement("summary", null, "stack trace"),
        React.createElement("pre", null, caught.info.componentStack))));
class Output extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.state = { caughtError: null };
    }
    componentDidCatch(error, info) {
        const caughtError = {
            error,
            info
        };
        this.setState({
            caughtError
        });
    }
    render() {
        if (this.state.caughtError) {
            return this.props.renderError(Object.assign(Object.assign({}, this.state.caughtError), { output: this.props.output, children: this.props.children }));
        }
        // We must pick only one child to render
        let chosenOne = null;
        if (this.props.output == null) {
            return null;
        }
        const output_type = this.props.output.output_type;
        // Find the first child element that matches something in this.props.data
        React.Children.forEach(this.props.children, child => {
            if (typeof child === "string" || typeof child === "number") {
                return;
            }
            const childElement = child;
            if (chosenOne) {
                // Already have a selection
                return;
            }
            if (!childElement ||
                typeof childElement !== "object" ||
                !("props" in childElement)) {
                return;
            }
            if (childElement.props && childElement.props.output_type) {
                const child_output_type = Array.isArray(childElement.props.output_type)
                    ? childElement.props.output_type
                    : [childElement.props.output_type];
                chosenOne = child_output_type.includes(output_type)
                    ? childElement
                    : null;
                return;
            }
        });
        // If we didn't find a match, render nothing
        if (chosenOne === null) {
            return null;
        }
        // Render the output component that handles this output type
        return React.cloneElement(chosenOne, { output: this.props.output });
    }
}
exports.Output = Output;
Output.defaultProps = {
    output: null,
    renderError: ErrorFallback
};
exports.default = Output;
