import { __decorate, __metadata } from "tslib";
import '@material/web/icon/icon.js';
import '@material/web/fab/fab.js';
import '../viewparts/play-group-info';
import '../board-list/board-tile-list';
import '../board-list/play-group-bar';
import gql from 'graphql-tag';
import { css, html } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { connect } from 'pwa-helpers/connect-mixin.js';
import { UPDATE_FAVORITES } from '@things-factory/fav-base/client';
import { openOverlay } from '@operato/layout';
import { navigate, PageView, store } from '@operato/shell';
import { client } from '@operato/graphql';
import { i18next, localize } from '@operato/i18n';
import { ScrollbarStyles } from '@operato/styles';
import { pulltorefresh } from '@operato/pull-to-refresh';
import { swipe, isMobileDevice } from '@things-factory/utils/src/index.js';
import { createPlayGroup, deletePlayGroup, fetchPlayGroup, fetchPlayGroupList, updateBoard, updatePlayGroup } from '../graphql';
let PlayListPage = class PlayListPage extends localize(i18next)(connect(store)(PageView)) {
    constructor() {
        super(...arguments);
        this.groups = [];
        this.boards = [];
        this.favorites = [];
    }
    get context() {
        var group = this.groups && this.groups.find(group => group.id === this.groupId);
        return {
            title: {
                icon: 'video_library',
                text: group ? group.name : 'Play List'
            },
            board_topmenu: true
        };
    }
    render() {
        return html `
      <play-group-bar
        .groups=${this.groups}
        .groupId=${this.groupId}
        target-page="play-list"
        @info-play-group=${e => this.onInfoPlayGroup(e.detail)}
      ></play-group-bar>

      <board-tile-list
        .favorites=${this.favorites}
        .boards=${this.boards}
        .group=${this.groupId}
        @info-board=${e => this.onInfoBoard(e.detail)}
        @delete-board=${e => this.onDeleteBoard(e.detail)}
        @refresh-favorites=${e => this.refreshFavorites()}
        @reordered=${e => this.onReorder(e.detail)}
        reorderable
      ></board-tile-list>

      <a id="play" .href=${'board-player/' + this.groupId}>
        <md-fab title="play">
          <md-icon slot="icon">play_arrow</md-icon>
        </md-fab>
      </a>
    `;
    }
    async refresh() {
        this.groups = (await fetchPlayGroupList()).playGroups.items;
        this.groups && (await this.refreshBoards());
    }
    async refreshBoards() {
        if (!this.groups) {
            await this.refresh();
            return;
        }
        if (!this.groupId) {
            let groupId = this.groups && this.groups[0] && this.groups[0].id;
            var newURL = new URL(window.location.href);
            newURL.pathname += `/${groupId}`;
            if (groupId) {
                navigate(newURL.href, true);
            }
            return;
        }
        if (this.groupId) {
            var playGroup = (await fetchPlayGroup(this.groupId)).playGroup;
            this.boards = playGroup ? playGroup.boards : [];
        }
        else {
            this.boards = [];
        }
        this.updateContext();
        var list = this.boardTileList;
        list.style.transition = '';
        list.style.transform = `translate3d(0, 0, 0)`;
    }
    async pageInitialized() {
        this.refresh();
    }
    async pageUpdated(changes, lifecycle) {
        if (this.active) {
            this.page = lifecycle.page;
            this.groupId = lifecycle.resourceId;
            await this.updateComplete;
            this.refreshBoards();
        }
    }
    stateChanged(state) {
        this.favorites = state.favorite.favorites;
    }
    firstUpdated() {
        var list = this.boardTileList;
        pulltorefresh({
            container: this.shadowRoot,
            scrollable: list,
            refresh: () => {
                return this.refresh();
            }
        });
        if (isMobileDevice()) {
            swipe({
                container: list,
                animates: {
                    dragging: async (d, opts) => {
                        var groups = this.groups;
                        var currentIndex = groups.findIndex(group => group.id == this.groupId);
                        if ((d > 0 && currentIndex <= 0) || (d < 0 && currentIndex >= groups.length - 1)) {
                            /* TODO blocked gesture */
                            return false;
                        }
                        list.style.transform = `translate3d(${d}px, 0, 0)`;
                    },
                    aborting: async (opts) => {
                        list.style.transition = 'transform 0.3s';
                        list.style.transform = `translate3d(0, 0, 0)`;
                        setTimeout(() => {
                            list.style.transition = '';
                        }, 300);
                    },
                    swiping: async (d, opts) => {
                        var groups = this.groups;
                        var currentIndex = groups.findIndex(group => group.id == this.groupId);
                        if ((d > 0 && currentIndex <= 0) || (d < 0 && currentIndex >= groups.length - 1)) {
                            list.style.transition = '';
                            list.style.transform = `translate3d(0, 0, 0)`;
                        }
                        else {
                            list.style.transition = 'transform 0.3s';
                            list.style.transform = `translate3d(${d < 0 ? '-100%' : '100%'}, 0, 0)`;
                            navigate(`${this.page}/${groups[currentIndex + (d < 0 ? 1 : -1)].id}`);
                        }
                    }
                }
            });
        }
    }
    async onInfoBoard(board) {
        openOverlay('viewpart-info', {
            template: html `
        <board-info
          .board=${board}
          .groupId=${this.groupId}
          @update-board=${e => this.onUpdateBoard(e.detail)}
          @delete-board=${e => this.onDeleteBoard(e.detail)}
          @join-playgroup=${e => this.onJoinPlayGroup(e.detail)}
          @leave-playgroup=${e => this.onLeavePlayGroup(e.detail)}
        ></board-info>
      `
        });
    }
    async onInfoPlayGroup(group) {
        openOverlay('viewpart-info', {
            template: html `
        <play-group-info
          .playGroup=${group}
          @update-play-group=${e => this.onUpdatePlayGroup(e.detail)}
          @delete-play-group=${e => this.onDeletePlayGroup(e.detail)}
          @create-play-group=${e => this.onCreatePlayGroup(e.detail)}
        ></play-group-info>
      `
        });
    }
    async onCreatePlayGroup(playGroup) {
        try {
            await createPlayGroup(playGroup);
            this._notify('info', i18next.t('text.play-group created', { playGroup: playGroup.name }));
        }
        catch (ex) {
            this._notify('error', ex, ex);
        }
        this.refresh();
    }
    async onUpdatePlayGroup(playGroup) {
        try {
            await updatePlayGroup(playGroup);
            this._notify('info', i18next.t('text.play-group updated', { playGroup: playGroup.name }));
        }
        catch (ex) {
            this._notify('error', ex, ex);
        }
        this.refresh();
    }
    async onDeletePlayGroup(playGroup) {
        try {
            await deletePlayGroup(playGroup.id);
            this._notify('info', i18next.t('text.play-group deleted', { playGroup: playGroup.name }));
        }
        catch (ex) {
            this._notify('error', ex, ex);
        }
        this.refresh();
    }
    async onUpdateBoard(board) {
        try {
            await updateBoard(board);
            this._notify('info', i18next.t('text.board updated', { board: board.name }));
        }
        catch (ex) {
            this._notify('error', ex, ex);
        }
        this.refreshBoards();
    }
    async onDeleteBoard(board) {
        const playGroup = this.groups && this.groups.find(group => group.id === this.groupId);
        await this.onLeavePlayGroup({ board, playGroup });
    }
    async onJoinPlayGroup({ board, playGroup }) {
        try {
            await client.mutate({
                mutation: gql `
          mutation JoinPlayGroup($id: String!, $boardIds: [String!]!) {
            joinPlayGroup(id: $id, boardIds: $boardIds) {
              id
            }
          }
        `,
                variables: {
                    id: playGroup.id,
                    boardIds: [board.id]
                }
            });
            this._notify('info', i18next.t('text.joined into play-group', { board: board.name, playGroup: playGroup.name }));
        }
        catch (ex) {
            this._notify('error', ex, ex);
        }
        this.refresh();
    }
    async onLeavePlayGroup({ board, playGroup }) {
        try {
            await client.mutate({
                mutation: gql `
          mutation ($id: String!, $boardIds: [String!]!) {
            leavePlayGroup(id: $id, boardIds: $boardIds) {
              id
            }
          }
        `,
                variables: {
                    id: playGroup.id,
                    boardIds: [board.id]
                }
            });
            this._notify('info', i18next.t('text.leaved from play-group', { board: board.name, playGroup: playGroup.name }));
        }
        catch (ex) {
            this._notify('error', ex, ex);
        }
        this.refresh();
    }
    async onReorder({ boardIds, groupId }) {
        try {
            const response = await client.mutate({
                mutation: gql `
          mutation ($id: String!, $boardIds: [String!]!) {
            reorderPlayGroup(id: $id, boardIds: $boardIds) {
              id
              name
            }
          }
        `,
                variables: {
                    id: groupId,
                    boardIds
                }
            });
            const playGroup = response.data.reorderPlayGroup;
            this._notify('info', i18next.t('text.reorder play-group', { playGroup: playGroup.name }));
        }
        catch (ex) {
            this._notify('error', ex, ex);
        }
        this.refresh();
    }
    async refreshFavorites() {
        const response = await client.query({
            query: gql `
        query {
          myFavorites {
            id
            routing
          }
        }
      `
        });
        store.dispatch({
            type: UPDATE_FAVORITES,
            favorites: response.data.myFavorites.map(favorite => favorite.routing)
        });
    }
    _notify(level, message, ex) {
        document.dispatchEvent(new CustomEvent('notify', {
            detail: {
                level,
                message,
                ex
            }
        }));
    }
};
PlayListPage.styles = [
    ScrollbarStyles,
    css `
      :host {
        display: flex;
        flex-direction: column;
        position: relative;

        overflow: hidden;
      }

      board-tile-list {
        flex: 1;
        overflow-y: auto;
      }

      #play {
        position: absolute;
        bottom: 15px;
        right: 16px;
        text-decoration: auto;
      }
    `
];
__decorate([
    property({ type: String }),
    __metadata("design:type", String)
], PlayListPage.prototype, "groupId", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Array)
], PlayListPage.prototype, "groups", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Array)
], PlayListPage.prototype, "boards", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Array)
], PlayListPage.prototype, "favorites", void 0);
__decorate([
    query('board-tile-list'),
    __metadata("design:type", HTMLElement)
], PlayListPage.prototype, "boardTileList", void 0);
PlayListPage = __decorate([
    customElement('play-list-page')
], PlayListPage);
export { PlayListPage };
//# sourceMappingURL=play-list-page.js.map