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 { SettingsArea } from '../../settings/SettingsArea';
import { SiteAdminAlert } from '../../site-admin/SiteAdminAlert';
import { createAggregateError, isErrorLike } from '../../util/errors';
import { OrgAccountArea } from '../account/OrgAccountArea';
import { OrgHeader } from './OrgHeader';
import { OrgInvitationPage } from './OrgInvitationPage';
import { OrgMembersPage } from './OrgMembersPage';
import { OrgOverviewPage } from './OrgOverviewPage';
function queryOrganization(args) {
    return queryGraphQL(gql `
            query Organization($name: String!) {
                organization(name: $name) {
                    __typename
                    id
                    name
                    displayName
                    url
                    settingsURL
                    viewerPendingInvitation {
                        id
                        sender {
                            username
                            displayName
                            avatarURL
                            createdAt
                        }
                        respondURL
                    }
                    viewerIsMember
                    viewerCanAdminister
                    createdAt
                }
            }
        `, args).pipe(map(({ data, errors }) => {
        if (!data || !data.organization) {
            throw createAggregateError(errors);
        }
        return data.organization;
    }));
}
const NotFoundPage = () => (React.createElement(HeroPage, { icon: MapSearchIcon, title: "404: Not Found", subtitle: "Sorry, the requested organization was not found." }));
/**
 * An organization's public profile area.
 */
export class OrgArea extends React.Component {
    constructor() {
        super(...arguments);
        this.state = {};
        this.routeMatchChanges = new Subject();
        this.refreshRequests = new Subject();
        this.subscriptions = new Subscription();
        this.onDidRespondToInvitation = () => this.refreshRequests.next();
        this.onDidUpdateOrganization = () => this.refreshRequests.next();
    }
    componentDidMount() {
        // Changes to the route-matched org name.
        const nameChanges = this.routeMatchChanges.pipe(map(({ name }) => name), distinctUntilChanged());
        // Fetch organization.
        this.subscriptions.add(combineLatest(nameChanges, merge(this.refreshRequests.pipe(mapTo(false)), of(true)))
            .pipe(switchMap(([name, forceRefresh]) => {
            return queryOrganization({ name }).pipe(catchError(error => [error]), map(c => ({ orgOrError: c })), 
            // Don't clear old org data while we reload, to avoid unmounting all components during
            // loading.
            startWith(forceRefresh ? { orgOrError: 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.orgOrError) {
            return null; // loading
        }
        if (isErrorLike(this.state.orgOrError)) {
            return (React.createElement(HeroPage, { icon: AlertCircleIcon, title: "Error", subtitle: upperFirst(this.state.orgOrError.message) }));
        }
        const transferProps = {
            authenticatedUser: this.props.user,
            org: this.state.orgOrError,
            onOrganizationUpdate: this.onDidUpdateOrganization,
            extensions: this.props.extensions,
        };
        if (this.props.location.pathname === `${this.props.match.url}/invitation`) {
            // The OrgInvitationPage is displayed without the OrgHeader because it is modal-like.
            return React.createElement(OrgInvitationPage, Object.assign({}, transferProps, { onDidRespondToInvitation: this.onDidRespondToInvitation }));
        }
        return (React.createElement("div", { className: "org-area area--vertical" },
            React.createElement(OrgHeader, Object.assign({ className: "area--vertical__header" }, this.props, transferProps)),
            React.createElement("div", { className: "org-area__content area--vertical__content" },
                React.createElement("div", { className: "org-area__content-inner area--vertical__content-inner" },
                    React.createElement(Switch, null,
                        React.createElement(Route, { path: this.props.match.url, key: "hardcoded-key" // see https://github.com/ReactTraining/react-router/issues/4578#issuecomment-334489490
                            , exact: true, 
                            // tslint:disable-next-line:jsx-no-lambda
                            render: routeComponentProps => (React.createElement(OrgOverviewPage, Object.assign({}, routeComponentProps, transferProps))) }),
                        React.createElement(Route, { path: `${this.props.match.url}/members`, key: "hardcoded-key" // see https://github.com/ReactTraining/react-router/issues/4578#issuecomment-334489490
                            , exact: true, 
                            // tslint:disable-next-line:jsx-no-lambda
                            render: routeComponentProps => (React.createElement(OrgMembersPage, Object.assign({}, routeComponentProps, transferProps))) }),
                        React.createElement(Route, { path: `${this.props.match.url}/settings`, key: "hardcoded-key" // see https://github.com/ReactTraining/react-router/issues/4578#issuecomment-334489490
                            , exact: true, 
                            // tslint:disable-next-line:jsx-no-lambda
                            render: routeComponentProps => (React.createElement(SettingsArea, Object.assign({}, routeComponentProps, transferProps, { subject: transferProps.org, isLightTheme: this.props.isLightTheme, extraHeader: React.createElement(React.Fragment, null,
                                    transferProps.authenticatedUser &&
                                        transferProps.org.viewerCanAdminister &&
                                        !transferProps.org.viewerIsMember && (React.createElement(SiteAdminAlert, { className: "sidebar__alert" },
                                        "Viewing settings for",
                                        ' ',
                                        React.createElement("strong", null, transferProps.org.name))),
                                    React.createElement("p", null, "Organization settings apply to all members. User settings override organization settings.")) }))) }),
                        React.createElement(Route, { path: `${this.props.match.url}/account`, key: "hardcoded-key" // see https://github.com/ReactTraining/react-router/issues/4578#issuecomment-334489490
                            , 
                            // tslint:disable-next-line:jsx-no-lambda
                            render: routeComponentProps => (React.createElement(OrgAccountArea, Object.assign({}, routeComponentProps, transferProps, { isLightTheme: this.props.isLightTheme }))) }),
                        React.createElement(Route, { key: "hardcoded-key", component: NotFoundPage }))))));
    }
}
//# sourceMappingURL=OrgArea.js.map