"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,
    React.createElement("h3", null, caught.error.toString()),
    React.createElement("details", null,
        React.createElement("summary", null, "stack trace"),
        React.createElement("pre", null, caught.info.componentStack))));
class RichMedia extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.state = {};
        this.choose = (children) => {
            // We must pick only one child to render
            let chosenOne = null;
            const data = this.props.data;
            // Find the first child element that matches something in this.props.data
            React.Children.forEach(children, child => {
                if (chosenOne) {
                    // Already have a selection
                    return;
                }
                const childElement = child;
                if (!childElement ||
                    typeof childElement !== "object" ||
                    !("type" in childElement)) {
                    return;
                }
                if (childElement.type === RichMedia) {
                    // One of our children is itself a RichMedia we can defer to
                    chosenOne = this.choose(childElement.props.children);
                    return;
                }
                if (childElement.props &&
                    childElement.props.mediaType &&
                    childElement.props.mediaType in data) {
                    chosenOne = childElement;
                    return;
                }
            });
            return chosenOne;
        };
    }
    componentDidCatch(error, info) {
        this.setState({ caughtError: { error, info } });
    }
    render() {
        if (this.state.caughtError) {
            return this.props.renderError(Object.assign(Object.assign({}, this.state.caughtError), { data: this.props.data, metadata: this.props.metadata, children: this.props.children }));
        }
        const chosenOne = this.choose(this.props.children);
        // If we didn't find a match, render nothing
        if (chosenOne === null || !chosenOne.props.mediaType) {
            return null;
        }
        const mediaType = chosenOne.props.mediaType;
        return React.cloneElement(chosenOne, {
            data: this.props.data[mediaType],
            metadata: this.props.metadata[mediaType]
        });
    }
}
exports.RichMedia = RichMedia;
RichMedia.defaultProps = {
    data: {},
    metadata: {},
    renderError: ErrorFallback
};
exports.default = RichMedia;
