var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import React from 'react';
import AppTile from '../app-tile';
import * as tileDimensions from '../app-tile/dimensions';
import shuffle from 'lodash.shuffle';
import createPlaceholderApp from '../../utilities/create-placeholder-app';
import Button from '../button';
import Box from '../box';
import Link from '../link';
import Paragraph from '../paragraph';
import autobind from 'autobind-decorator';
import { Inline, InlineBlock, Block, Col } from 'jsxstyle';
import track from '../../utilities/tracking';
import { variables as styleConst } from 'cf-style-const';
import { If, Then } from 'react-if';
import { translateHOC, TranslationKeys } from '../../utilities/i18n';
import request from '../../utilities/request';
import { declareFont } from '../../mixins/fonts';
declareFont('Open+Sans:300,400,600,700');
const WEEK_DURATION = 7 * 86400000;
export var Visibility;
(function (Visibility) {
    Visibility["Visible"] = "VISIBLE";
    Visibility["Hidden"] = "HIDDEN";
    Visibility["Dimissed"] = "DIMISSED";
    Visibility["SentFeedback"] = "SENT_FEEDBACK";
})(Visibility || (Visibility = {}));
export var FeedbackEvents;
(function (FeedbackEvents) {
    FeedbackEvents["Uninterested"] = "UNINTERESTED";
    FeedbackEvents["Irrelevant"] = "IRRELEVANT";
    FeedbackEvents["SeenIt"] = "SEEN_IT";
})(FeedbackEvents || (FeedbackEvents = {}));
class RelatedAppsBanner extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            visibility: Visibility.Visible,
            categories: [],
            appsByCategory: {},
            categoryIndex: -1,
            visibleAppsCount: 4
        };
        const now = Date.now();
        try {
            const dismissedAt = JSON.parse(window.localStorage.realatedAppsBannerDismissedAt || '""');
            const dateDismissed = new Date(dismissedAt);
            if (!isNaN(dateDismissed.valueOf())) {
                this.state.visibility = now - WEEK_DURATION >= dateDismissed.valueOf()
                    ? Visibility.Visible
                    : Visibility.Hidden;
            }
        }
        catch (error) {
            console.error(error);
        }
    }
    componentDidMount() {
        this.fetchCategoryData();
    }
    componentWillReceiveProps(nextProps) {
        if (this.props.categories !== nextProps.categories) {
            this.fetchCategoryData();
        }
    }
    get category() {
        return this.state.categories[this.state.categoryIndex];
    }
    dismiss() {
        window.localStorage.realatedAppsBannerDismissedAt = JSON.stringify(new Date());
        this.setState({
            visibility: Visibility.Dimissed
        });
        track({
            action: 'Dismissed',
            category: 'Promo Banner',
            label: this.props.categories.join(',')
        });
    }
    sendFeedback(kind) {
        this.setState({
            visibility: Visibility.SentFeedback
        });
        track({
            action: 'Feedback',
            category: 'Promo Banner',
            label: this.props.categories.join(','),
            value: kind
        });
    }
    fetchCategoryData() {
        const categoryPromises = this.props.categories.map((category) => {
            return request(`https://api.cloudflareapps.com/categories/${category}`)
                .then((category) => {
                return request(`https://api.cloudflareapps.com/apps/by-category/${category.id}`)
                    .then((apps) => {
                    return { category, apps };
                });
            });
        });
        Promise.all(categoryPromises).then((responses) => {
            const appsByCategory = {};
            const categories = [];
            responses.forEach(({ category, apps }) => {
                appsByCategory[category.id] = shuffle(apps);
                categories.push(category);
            });
            if (!categories.length) {
                console.warn('RelatedAppsBanner: No categories for given props', this.props);
                return;
            }
            this.setState({
                categoryIndex: Math.floor(Math.random() * categories.length),
                appsByCategory,
                categories
            });
        });
    }
    get visibleApps() {
        const { visibleAppsCount, categoryIndex } = this.state;
        let apps = [];
        if (categoryIndex >= 0) {
            apps = this.state.appsByCategory[this.category.id]
                .slice(0, visibleAppsCount);
        }
        // TODO: Create AppTilePlaceholder
        while (apps.length < visibleAppsCount) {
            apps.push(createPlaceholderApp({ id: `dummy-${apps.length}` }));
        }
        return apps;
    }
    render() {
        if (this.state.visibility === Visibility.Hidden)
            return null;
        return React.createElement(Box, { subtleBoxShadow: this.props.shadowType === 'subtle', props: {
                'data-component': 'related-apps-banner'
            }, display: 'flex', flex: '1 1 auto', padding: '1.2em' }, this.renderBody());
    }
    renderBody() {
        const { category, props: { t } } = this;
        if (this.state.visibility === Visibility.Dimissed) {
            return React.createElement(Col, { marginTop: '1em', flex: '1 1 auto', alignItems: 'center' },
                React.createElement(Block, { textAlign: 'center', component: 'h4' }, t(TranslationKeys.showRecommendationLessOften)),
                React.createElement(Block, { display: 'grid', gridGap: '1em', gridAutoRows: '1fr', gridTemplateColumns: '1fr 1fr 1fr', justifyContent: 'center', marginTop: '1.5em' },
                    React.createElement(Button, { type: 'transparent', props: {
                            onClick: this.sendFeedback.bind(null, FeedbackEvents.Uninterested)
                        } }, t(TranslationKeys.notInterested)),
                    React.createElement(Button, { type: 'transparent', props: {
                            onClick: this.sendFeedback.bind(null, FeedbackEvents.Irrelevant)
                        } }, t(TranslationKeys.notRelevant)),
                    React.createElement(Button, { type: 'transparent', props: {
                            onClick: this.sendFeedback.bind(null, FeedbackEvents.SeenIt)
                        } }, t(TranslationKeys.alreadySeenIt))));
        }
        if (this.state.visibility === Visibility.SentFeedback) {
            return React.createElement(Col, { flex: '1 1 auto', alignItems: 'center' },
                React.createElement(Block, { component: 'h4', textAlign: 'center' }, t(TranslationKeys.feedbackThankYou)));
        }
        return React.createElement(Col, { flex: '1 1 auto' },
            React.createElement(InlineBlock, { color: styleConst.colors.hail, fontSize: '2rem', width: '1em', lineHeight: '1em', textAlign: 'center', cursor: 'pointer', right: '0.5em', top: '0.6em', fontFamily: 'cloudflare-apps-icons', position: 'absolute', hoverColor: '#000', props: {
                    onClick: this.dismiss
                } }, "\u00D7"),
            React.createElement(Block, { component: 'header', minHeight: 54, marginBottom: '1em' },
                React.createElement(If, { condition: !!category },
                    React.createElement(Then, null, () => (React.createElement("div", null,
                        React.createElement(Block, { component: 'h3', fontWeight: 'normal', margin: '0 0 0.005em', fontSize: styleConst.fontSizes[4], paddingRight: '7rem' },
                            React.createElement(Inline, { fontWeight: 300 },
                                this.props.t(TranslationKeys.appsRelatedTo),
                                "\u00A0"),
                            React.createElement(Link, { props: {
                                    href: `${APPS_BASE_PATH}/category/${category.id}`,
                                    target: '_blank'
                                }, withInheritedColor: true, withMoreIconAfter: true, track: {
                                    action: 'Routed to category via banner',
                                    category: 'Promo Banner',
                                    value: category.id
                                }, fontWeight: 500 }, category.title)),
                        React.createElement(Paragraph, { fontWeight: 200, margin: 0, color: styleConst.night }, category.description)))))),
            React.createElement(Block, { display: 'grid', gridTemplateColumns: `repeat(auto-fit, minmax(${tileDimensions.width}px, 0fr))`, gridAutoRows: '1fr', gridGap: '1em', justifyContent: 'center', width: '100%' }, this.visibleApps.map(app => (React.createElement(AppTile, { app: app, key: app.id, recommendedCategory: category })))));
    }
}
RelatedAppsBanner.defaultProps = {};
__decorate([
    autobind
], RelatedAppsBanner.prototype, "dismiss", null);
__decorate([
    autobind
], RelatedAppsBanner.prototype, "sendFeedback", null);
RelatedAppsBanner.defaultProps = {
    shadowType: 'shadow'
};
export default translateHOC()(RelatedAppsBanner);
//# sourceMappingURL=related-apps-banner.js.map