var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

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 === "undefined" ? "undefined" : _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, { getAuthorization } from '../../utilities/request';
import { declareFont } from '../../mixins/fonts';
import { paths } from '../../utilities/routes';
import settle from '../../utilities/p-settle';
var APPS_BASE_PATH = paths.APPS_BASE_PATH,
    API_BASE_PATH = paths.API_BASE_PATH,
    CF_DASHBOARD_BASE_PATH = paths.CF_DASHBOARD_BASE_PATH;

declareFont('Open+Sans:300,400,600,700');
var 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 = {}));

var RelatedAppsBanner = function (_React$Component) {
    _inherits(RelatedAppsBanner, _React$Component);

    function RelatedAppsBanner(props) {
        _classCallCheck(this, RelatedAppsBanner);

        var _this = _possibleConstructorReturn(this, (RelatedAppsBanner.__proto__ || Object.getPrototypeOf(RelatedAppsBanner)).call(this, props));

        _this.state = {
            visibility: Visibility.Visible,
            categories: [],
            appsByCategory: {},
            categoryIndex: -1,
            visibleAppsCount: 4
        };
        var now = Date.now();
        try {
            var dismissedAt = JSON.parse(window.localStorage.realatedAppsBannerDismissedAt || '""');
            var 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);
        }
        return _this;
    }

    _createClass(RelatedAppsBanner, [{
        key: "componentDidMount",
        value: function componentDidMount() {
            this.fetchCategoriesAndApps();
        }
    }, {
        key: "componentWillReceiveProps",
        value: function componentWillReceiveProps(nextProps) {
            if (this.props.categories !== nextProps.categories) {
                this.fetchCategoriesAndApps();
            }
        }
    }, {
        key: "urlToCategory",
        value: function urlToCategory(category) {
            if (this.props.domain) {
                return CF_DASHBOARD_BASE_PATH + "/apps/" + this.props.domain + "/category/" + category.id;
            }
            return APPS_BASE_PATH + "/category/" + category.id;
        }
    }, {
        key: "dismiss",
        value: function dismiss() {
            window.localStorage.realatedAppsBannerDismissedAt = JSON.stringify(new Date());
            this.setState({
                visibility: Visibility.Dimissed
            });
            track({
                action: 'Dismissed',
                category: 'Promo Banner',
                label: this.props.categories.join(',')
            });
        }
    }, {
        key: "sendFeedback",
        value: function sendFeedback(kind) {
            this.setState({
                visibility: Visibility.SentFeedback
            });
            track({
                action: 'Feedback',
                category: 'Promo Banner',
                label: this.props.categories.join(','),
                value: kind
            });
        }
    }, {
        key: "fetchCategoriesAndApps",
        value: function fetchCategoriesAndApps() {
            var _this2 = this;

            var parse = function parse(responses) {
                var appsByCategory = {};
                var categories = [];
                responses.forEach(function (_ref) {
                    var category = _ref.category,
                        apps = _ref.apps;

                    appsByCategory[category.id] = shuffle(apps);
                    categories.push(category);
                });
                if (!categories.length) {
                    console.warn('RelatedAppsBanner: No categories for given props', _this2.props);
                    return;
                }
                _this2.setState({
                    categoryIndex: Math.floor(Math.random() * categories.length),
                    appsByCategory: appsByCategory,
                    categories: categories
                });
            };
            // Fetch categories.
            var categoryPromises = this.props.categories.map(function (category) {
                return request(API_BASE_PATH + "/categories/" + category).then(function (category) {
                    return category;
                });
            });
            Promise.all(categoryPromises).then(function (categories) {
                if (getAuthorization()) {
                    // Fetch recommended apps.
                    var appPromises = categories.map(function (category) {
                        // Fetch recommended app IDs.
                        return request(API_BASE_PATH + "/apps/recommend/?categories=" + category.id).then(function (appIds) {
                            var appPromises = appIds.map(function (id) {
                                return request(API_BASE_PATH + "/apps/" + id).then(function (app) {
                                    return app;
                                });
                            });
                            // NOTE: The recommended apps endpoint occasionally returns app IDs
                            // that map to deleted apps. They should be filtered out in the short term.
                            return settle(appPromises).then(function (results) {
                                var apps = results.filter(function (result) {
                                    return !result.isRejected && result.value;
                                }).map(function (result) {
                                    return result.value;
                                }).filter(function (app) {
                                    return app.userVisible && app.adminVisible;
                                });
                                return { category: category, apps: apps };
                            });
                        });
                    });
                    Promise.all(appPromises).then(parse);
                } else {
                    // Fetch apps matching category.
                    var _categoryPromises = _this2.props.categories.map(function (category) {
                        return request(API_BASE_PATH + "/categories/" + category).then(function (category) {
                            return request(API_BASE_PATH + "/apps/by-category/" + category.id).then(function (apps) {
                                return { category: category, apps: apps };
                            });
                        });
                    });
                    Promise.all(_categoryPromises).then(parse);
                }
            });
        }
    }, {
        key: "render",
        value: function 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());
        }
    }, {
        key: "renderBody",
        value: function renderBody() {
            var _this3 = this;

            var category = this.category,
                t = this.props.t;

            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
                } }, "\xD7"), React.createElement(Block, { component: 'header', minHeight: 54, padding: '0 .1em', marginBottom: '1em' }, React.createElement(If, { condition: !!category }, React.createElement(Then, null, function () {
                return 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 }, _this3.props.t(TranslationKeys.appsRelatedTo), "\xA0"), React.createElement(Link, { props: {
                        href: _this3.urlToCategory(category),
                        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', maxWidth: "calc(" + tileDimensions.width * 4 + ")", alignSelf: 'center', justifyContent: 'space-between', gridTemplateColumns: "repeat(auto-fill, " + tileDimensions.width + "px)", gridAutoRows: '1fr', gridGap: '1em', width: '100%' }, this.visibleApps.map(function (app) {
                return React.createElement(AppTile, { app: app, key: app.id, domain: _this3.props.domain, recommendedCategory: category });
            })));
        }
    }, {
        key: "category",
        get: function get() {
            return this.state.categories[this.state.categoryIndex];
        }
    }, {
        key: "visibleApps",
        get: function get() {
            var _state = this.state,
                visibleAppsCount = _state.visibleAppsCount,
                categoryIndex = _state.categoryIndex;

            var 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;
        }
    }]);

    return RelatedAppsBanner;
}(React.Component);

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