import { LitElement, html, css } from 'lit-element'

import '@polymer/app-layout/app-drawer/app-drawer'
import '@polymer/app-layout/app-drawer-layout/app-drawer-layout'

import { connect } from 'pwa-helpers/connect-mixin.js'
import { installRouter } from 'pwa-helpers/router.js'
import { installOfflineWatcher } from 'pwa-helpers/network.js'
import { installMediaQueryWatcher } from 'pwa-helpers/media-query.js'

import { store, navigate, updateDrawerState, updateOffline } from '../reducer/store'
import { i18next } from '../components/i18next'

import { ThingsShellTheme } from '../styles/things-shell-theme'
import { SharedStyles } from '../styles/shared-styles'

import './auth-router'

import '../layouts/shell-drawer/shell-drawer'

import '../pages/board-list/board-list'
import '../pages/board-modeler/board-modeler'
import '../pages/board-viewer-page/board-viewer-page'
import '../pages/board-player-page/board-player-page'
import '../pages/setting-font/setting-font'
import '../pages/setting-file/setting-file'
import '../pages/setting-datasource/setting-datasource'
import '../pages/setting-publisher/setting-publisher'
import '../pages/setting-security/setting-security'

import '../pages/auth/auth-signin'
import '../pages/auth/auth-signup'
import '../pages/auth/user-profile'

import '../pages/page-404/page-404'

import '../components/things-provider/things-provider'
import '../components/things-snackbar'
import ThingsSnackbar from '../components/things-snackbar'

export default class AppShell extends connect(store)(LitElement) {
  constructor() {
    super()
  }

  static get is() {
    return 'app-shell'
  }

  static get properties() {
    return {
      // statePath: 'route.page'
      page: String,
      // statePath: 'route.rootPattern'
      // rootPattern: String,
      // statePath: 'process.app-version'
      appVersion: String,
      // statePath: 'process.node-env'
      ENV: String,
      // statePath: 'boardCurrent.name'
      mainTitle: String,
      // statePath: 'auth.user'
      user: Object,
      // statePath: 'auth.token'
      token: String,
      // statePath: 'auth.error'
      authError: Object,
      /* drawer의 상태를 반영함 */
      drawerOpened: Boolean,
      /* drawer가 되어야하는 상태를 지시함 */
      // statePath: 'drawer.collapsed'
      collapsed: Boolean,
      // Reference Provider
      provider: Object,
      meta: String
    }
  }

  firstUpdated() {
    /* router를 install 한다. */
    installRouter(location => {
      return store.dispatch(navigate(decodeURIComponent(location.pathname)))
    })
    installOfflineWatcher(offline => store.dispatch(updateOffline(offline)))
    installMediaQueryWatcher(`(min-width: 460px)`, () => store.dispatch(updateDrawerState(false)))

    i18next.on('initialized', () => {
      store.dispatch({
        type: 'SET-LOCALE',
        locale: i18next.language
      })

      this.onLocaleChanged()
    })
    i18next.on('languageChanged', () => this.onLocaleChanged())

    // if (this.shadowRoot.getElementById('contextmenu')) {
    //   this.set('contextmenu', this.shadowRoot.getElementById('contextmenu'))
    //   window.addEventListener('contextmenu', this.onContextmenu)
    // }
  }

  updated(change) {
    change.has('drawerOpened') && store.dispatch(updateDrawerState(this.drawerOpened))
    change.has('collapsed') && this.onDrawerCollapsedChanged(this.collapsed)
    change.has('page') && this.onPageChanged(this.page)
    change.has('authError') && this.onAuthErrorChanged()
  }

  onAuthErrorChanged() {
    if (this.authError) {
      ThingsSnackbar.toast(this.authError)
    }
  }

  stateChanged(state) {
    this.page = state.route.page
    this.appVersion = state.process['app-version']
    this.ENV = state.process['node-env']
    this.mainTitle = state.boardCurrent.name
    this.user = state.auth.user
    this.token = state.auth.token
    this.authError = state.auth.error
    this.collapsed = state.drawer.collapsed
  }

  static get styles() {
    return [
      ThingsShellTheme,
      SharedStyles,
      css`
        :host {
          display: block;
        }

        app-drawer-layout:not([narrow]) [drawer-toggle] {
          display: none;
        }

        shell-drawer {
          height: 100%;
          -webkit-overflow-scrolling: touch;
        }

        app-drawer div {
          height: 100%;
        }

        main {
          height: 100%;

          display: flex;
          flex-direction: column;
        }

        main > * {
          display: none;
        }

        main > *[active] {
          flex: 1;
          display: flex;
        }

        .meta {
          pointer-events: none;
          font-size: 0.5em;
          opacity: 0.5;
          user-select: none;
          cursor: default;
          position: fixed;
          bottom: 8px;
          right: 8px;
        }
      `
    ]
  }

  render() {
    return html`
      <auth-router></auth-router>

      <things-provider @change=${e => (this.provider = e.target.refProvider)}> </things-provider>

      <app-drawer-layout
        id="drawerlayout"
        fullbleed
        ?narrow=${this.narrow}
        @narrow-changed=${e => (this.narrow = e.detail.value)}
        disable-swipe
      >
        <!-- Drawer content -->
        <app-drawer
          slot="drawer"
          @opened-changed=${e => (this.drawerOpened = e.detail.value)}
          ?opened=${this.drawerOpened}
        >
          <shell-drawer .started=${this.token}></shell-drawer>
        </app-drawer>

        <!-- Main content -->
        <main>
          ${this.token
            ? html`
                <board-list ?active=${this.isActivePage('list')}></board-list>
                <board-modeler
                  ?active=${this.isActivePage('modeler')}
                  .model=${this.model}
                  .provider=${this.provider}
                ></board-modeler>
                <board-viewer-page
                  ?active=${this.isActivePage('viewer')}
                  .provider=${this.provider}
                ></board-viewer-page>
                <board-player-page
                  ?active=${this.isActivePage('player')}
                  .provider=${this.provider}
                ></board-player-page>
                <setting-font ?active=${this.isActivePage('setting-font')}></setting-font>
                <setting-file ?active=${this.isActivePage('setting-file')}></setting-file>
                <setting-datasource ?active=${this.isActivePage('setting-datasource')}></setting-datasource>
                <setting-publisher ?active=${this.isActivePage('setting-publisher')}></setting-publisher>
                <setting-security ?active=${this.isActivePage('setting-security')}></setting-security>

                <auth-signin ?active=${this.isActivePage('signin')}></auth-signin>
                <auth-signup ?active=${this.isActivePage('signup')}></auth-signup>
                <user-profile ?active=${this.isActivePage('user-profile')} .user=${this.user}></user-profile>
              `
            : html`
                <auth-signin ?active=${this.isActivePage('signin')}></auth-signin>
                <auth-signup ?active=${this.isActivePage('signup')}></auth-signup>
              `}
          <page-404 ?active=${this.isActivePage('page-404')}></page-404>
        </main>
      </app-drawer-layout>

      <aside class="meta">${this.meta}</aside>

      <things-snackbar hidden></things-snackbar>
    `
  }

  isActivePage(page) {
    var current = ['list-recent', 'list-by-group', 'list-by-playgroup'].indexOf(this.page) > -1 ? 'list' : this.page
    return page == current
  }

  get drawerlayout() {
    return this.shadowRoot.getElementById('drawerlayout')
  }

  onPageChanged(page = 'list-recent') {
    switch (page) {
      case 'modeler':
      case 'viewer':
      case 'signin':
      case 'signup':
        this.drawerlayout.forceNarrow = true
        break
      default:
        this.drawerlayout.forceNarrow = false
    }

    // Close a non-persistent drawer when the page & route are changed.
    if (!this.drawerlayout.drawer.persistent) {
      this.drawerlayout.drawer.close()
    }
  }

  onDrawerCollapsedChanged(collapsed) {
    if (collapsed == !this.drawerOpened) return

    var drawerlayout = this.drawerlayout

    if ((drawerlayout.forceNarrow && this.page != 'modeler') || !drawerlayout.narrow) {
      drawerlayout.forceNarrow = collapsed
      requestAnimationFrame(() => dispatchEvent(new Event('resize')))
    } else {
      collapsed ? drawerlayout.drawer.close() : drawerlayout.drawer.open()
    }
  }

  onLocaleChanged() {
    this.meta = i18next.t('env-mention', {
      version: this.appVersion,
      env: this.ENV
    })
  }

  // onContextmenu(e) {
  //   e.preventDefault()

  //   var contextmenu = e.target.contextmenu
  //   contextmenu.show(e.clientX, e.clientY, [
  //     {
  //       name: 'afdasfasdfdasfasfsa',
  //       action: () => {
  //         alert('a!')
  //       }
  //     },
  //     {
  //       name: 'afdasfasdfdasfasfsa',
  //       action: () => {
  //         alert('a!')
  //       }
  //     },
  //     {
  //       name: 'afdasfasdfdasfasfsa',
  //       action: () => {
  //         alert('a!')
  //       }
  //     }
  //   ])
  // }

  _showPage404() {
    this.page = 'page-404'
  }
}

customElements.define(AppShell.is, AppShell)
