import { upperFirst } from 'lodash';
import AlertCircleIcon from 'mdi-react/AlertCircleIcon';
import MapSearchIcon from 'mdi-react/MapSearchIcon';
import * as React from 'react';
import { Route, Switch } from 'react-router';
import { combineLatest, merge, of, Subject, Subscription } from 'rxjs';
import { catchError, distinctUntilChanged, map, mapTo, startWith, switchMap } from 'rxjs/operators';
import { gql, queryGraphQL } from '../../backend/graphql';
import { HeroPage } from '../../components/HeroPage';
import { createAggregateError, isErrorLike } from '../../util/errors';
import { UserAreaHeader } from './UserAreaHeader';
const fetchUser = (args) => queryGraphQL(gql `
            query User($username: String!) {
                user(username: $username) {
                    __typename
                    id
                    username
                    displayName
                    url
                    settingsURL
                    avatarURL
                    viewerCanAdminister
                    siteAdmin
                    createdAt
                    emails {
                        email
                        verified
                    }
                    organizations {
                        nodes {
                            id
                            displayName
                            name
                        }
                    }
                }
            }
        `, args).pipe(map(({ data, errors }) => {
    if (!data || !data.user) {
        throw createAggregateError(errors);
    }
    return data.user;
}));
const NotFoundPage = () => (React.createElement(HeroPage, { icon: MapSearchIcon, title: "404: Not Found", subtitle: "Sorry, the requested user was not found." }));
/**
 * A user's public profile area.
 */
export class UserArea extends React.Component {
    constructor() {
        super(...arguments);
        this.state = {};
        this.routeMatchChanges = new Subject();
        this.refreshRequests = new Subject();
        this.subscriptions = new Subscription();
        this.onDidUpdateUser = () => this.refreshRequests.next();
    }
    componentDidMount() {
        // Changes to the route-matched username.
        const usernameChanges = this.routeMatchChanges.pipe(map(({ username }) => username), distinctUntilChanged());
        // Fetch user.
        this.subscriptions.add(combineLatest(usernameChanges, merge(this.refreshRequests.pipe(mapTo(false)), of(true)))
            .pipe(switchMap(([username, forceRefresh]) => {
            return fetchUser({ username }).pipe(catchError(error => [error]), map(c => ({ userOrError: c })), 
            // Don't clear old user data while we reload, to avoid unmounting all components during
            // loading.
            startWith(forceRefresh ? { userOrError: undefined } : {}));
        }))
            .subscribe(stateUpdate => this.setState(stateUpdate), err => console.error(err)));
        this.routeMatchChanges.next(this.props.match.params);
    }
    componentWillReceiveProps(props) {
        if (props.match.params !== this.props.match.params) {
            this.routeMatchChanges.next(props.match.params);
        }
    }
    componentWillUnmount() {
        this.subscriptions.unsubscribe();
    }
    render() {
        if (!this.state.userOrError) {
            return null; // loading
        }
        if (isErrorLike(this.state.userOrError)) {
            return (React.createElement(HeroPage, { icon: AlertCircleIcon, title: "Error", subtitle: upperFirst(this.state.userOrError.message) }));
        }
        const context = {
            url: this.props.match.url,
            user: this.state.userOrError,
            onDidUpdateUser: this.onDidUpdateUser,
            authenticatedUser: this.props.user,
            extensions: this.props.extensions,
            isLightTheme: this.props.isLightTheme,
            userAccountAreaRoutes: this.props.userAccountAreaRoutes,
            userAccountSideBarItems: this.props.userAccountSideBarItems,
        };
        return (React.createElement("div", { className: "user-area area--vertical" },
            React.createElement(UserAreaHeader, Object.assign({ className: "area--vertical__header" }, this.props, context, { navItems: this.props.userAreaHeaderNavItems })),
            React.createElement("div", { className: "area--vertical__content" },
                React.createElement("div", { className: "area--vertical__content-inner" },
                    React.createElement(Switch, null,
                        this.props.userAreaRoutes.map(({ path, exact, render, condition = () => true }) => condition(context) && (React.createElement(Route, { path: this.props.match.url + path, key: "hardcoded-key" // see https://github.com/ReactTraining/react-router/issues/4578#issuecomment-334489490
                            , exact: exact, 
                            // tslint:disable-next-line:jsx-no-lambda
                            render: routeComponentProps => render(Object.assign({}, context, routeComponentProps)) }))),
                        React.createElement(Route, { key: "hardcoded-key", component: NotFoundPage }))))));
    }
}
//# sourceMappingURL=UserArea.js.map