<template>
  <div class="theme-container" id="screenshot-wrap">
    <splitpanes vertical>
      <pane size="25" style="min-width: 200px">
        <skote-sidebar :dashboardType="dashboardType" :viewMode="viewMode" :showIcons="isEditingDashboard"
        :currentUser="currentUser"
        :selectedPanel="selectedPanel"
        :selectedDashboard="selectedDashboard"
        :selectedProject="selectedProject"
        :compareTreeData="compareTreeData"
        :dashboardService="dashboardService"
        :treeService="treeService"
        :entityService="entityService"
        :orgService="orgService"
        :dataInsightService="dataInsightService"
        :toastr="toastr"
        @select-panel="onSelectDashboardPanel"
        @go-back="onGoBack"></skote-sidebar>
      </pane>
      <pane size="100">
        <div class="content-wrap">
          <skote-header
            :viewMode="viewMode"
            :dashboards="dashboards"
            :dashboardType="dashboardType"
            :currentUser="currentUser"
            :selectedTheme="selectedTheme"
            :selectedDashboard="selectedDashboard"
            :selectedPanel="selectedPanel"
            :dashboardService="dashboardService"
            :dashboardSocketToken="dashboardSocketToken"
            :imageService="imageService"
            :selectedProject="selectedProject"
            :compareTreeData="compareTreeData"
            :treeService="treeService"
            :entityService="entityService"
            :orgService="orgService"
            :dataInsightService="dataInsightService"
            :commonService="commonService"
            :toastr="toastr"
            @set-panel="sidebarSetPanel"
            @on-change-mode="onChangeMode"
            @save-dashboard-panel="onSaveDashboardPanel"
            @cancel-edit-dashboard="onCancelEditDashboard"
            @capture-dashboard="captureDashboard"
            @save-panel-realtime-historical-settings="savePanelRealtimeHistoricalSettings">
          </skote-header>
          <div class="widgets-wrap" :style="{background: (selectedDashboard ? selectedDashboard.settings.background_color : '#f8f8f8')}">
            <div class="layout-container">
              <grid-layout
                  :layout.sync="layout"
                  :col-num="120"
                  :row-height="10"
                  :is-draggable="isEditingDashboard"
                  :is-resizable="isEditingDashboard"
                  :is-mirrored="false"
                  :vertical-compact="true"
                  :margin="[10, 10]"
                  :use-css-transforms="true"
                >
                  <grid-item v-for="item in layout" :id="item.i" class="shine" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i" :key="item.key" @resized="resizeHighchartWidget(item)" :style="{background: getCardBackgroundColor(item)}">
                    <template v-if="widgetObject[item.i]">
                      <widget :ref="'widget' + getWidgetInstanceId(item)"
                      :widgetId="getWidgetId(item)"
                      :widgetInstanceId="getWidgetInstanceId(item)"
                      :widgetType="item.type"
                      :layoutItem="item"
                      :isEditingDashboard="isEditingDashboard"
                      :dashboardType="dashboardType"
                      :currentUser="currentUser"
                      :selectedDashboard="selectedDashboard"
                      :selectedPanel="selectedPanel"
                      :dashboardSocketToken="dashboardSocketToken"
                      :dashboardService="dashboardService"
                      :imageService="imageService"
                      :selectedProject="selectedProject"
                      :compareTreeData="compareTreeData"
                      :treeService="treeService"
                      :entityService="entityService"
                      :orgService="orgService"
                      :dataInsightService="dataInsightService"
                      @on-delete-widget-instance="onDeleteWidgetInstance"
                      ></widget>
                    </template>
                  </grid-item>
                </grid-layout>
            </div>
          </div>
        </div>
      </pane>
    </splitpanes>
  </div>
</template>

<script>
import dasbhoardEventBus from './dashboardBus'
import VueGridLayout from 'vue-grid-layout'
import html2canvas from 'html2canvas'
import { saveAs } from 'file-saver'
import { Splitpanes, Pane } from 'splitpanes'
import skoteSidebar from './themes/sidebar.vue'
import skoteHeader from './themes/header.vue'
import { Socket } from 'phoenix-socket'
import { socketUrl } from './constants/config'
import widget from './widget/widget.vue'

export default {
  components: {
    Splitpanes,
    Pane,
    GridLayout: VueGridLayout.GridLayout,
    GridItem: VueGridLayout.GridItem,
    skoteSidebar,
    skoteHeader,
    widget
  },
  props: {
    viewMode: {
      default: false
    },
    dashboards: {
      type: Array
    },
    dashboardType: {
      type: String,
      default: 'userDashboard'
    },
    currentUser: {},
    selectedDashboard: {},
    selectedPanel: {},
    dashboardSocketToken: {},
    selectedTheme: {},
    selectedProject: {},
    compareTreeData: {},
    dashboardService: {},
    commonService: {},
    treeService: {},
    entityService: {},
    orgService: {},
    dataInsightService: {},
    imageService: {},
    loader: {},
    toastr: {}
  },
  data () {
    return {
      widgetObject: {},
      isEditingDashboard: false,
      layout: [],
      realTimeHistoricalSettings: {},
      realTimeHistoricalSelectedWidget: null,
      channel: null
    }
  },
  methods: {
    onGoBack () {
      this.$emit('show-all')
    },
    sidebarSetPanel (panel) {
      this.$emit('set-panel', panel)
    },
    getUniqueKey () {
      let result = ''
      let characters = 'abcdefghijklmnopqrstuvwxyz0123456789'
      let charactersLength = characters.length
      for (var i = 0; i < 20; i++) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength))
      }
      return result
    },
    onChangeMode (mode) {
      if (mode === 'edit') {
        this.isEditingDashboard = true
      } else {
        this.isEditingDashboard = false
      }
    },
    getCardBackgroundColor (item) {
      if (this.getVisualProperties(item).chart || this.getVisualProperties(item).card) {
        let widgetSettings = (this.getVisualProperties(item).chart || this.getVisualProperties(item).card)
        return widgetSettings ? widgetSettings.backgroundColor : '#ffffff'
      } else {
        return this.getVisualProperties(item).background_and_position ? this.getVisualProperties(item).background_and_position.background : '#ffffff'
      }
    },
    getVisualProperties (item) {
      return this.widgetObject[item.i] ? this.widgetObject[item.i].visual_properties : {}
    },
    onSelectDashboardPanel (panel) {
      if (this.dashboardType === 'exportedDashboard') {
        this.loadDashboardPanel(panel, true)
      } else {
        this.loadDashboardPanel(panel, true)
        this.createPanelChannel(this.selectedPanel.id)
      }
    },
    setDashboardPanel (panel) {
      this.$emit('set-panel', panel)

      this.$_.forEach(panel.widgets || [], (widget) => {
        this.widgetObject[widget.id] = widget
      })

      let layout = this.$_.map(panel.widget_layouts || {}, (setting, id) => {
        return this.$_.merge(setting, { i: id, key: this.getUniqueKey() })
      })

      this.layout = this.$_.filter(layout, (item) => {
        return this.widgetObject[item.i]
      })
    },
    loadDashboardPanel (panel, showLoader = false) {
      this.layout = []
      let loader = this.loader.show()

      let config = { orgId: this.selectedDashboard.org_id, dashboardId: this.selectedDashboard.id, id: panel.id }
      this.dashboardService
        .loadDashboardPanel(config)
        .then((panel) => {
          this.setDashboardPanel(panel)
          loader.hide()
        })
    },
    loadExportedDashboardPanel () {
      this.layout = []
      let loader = this.loader.show()

      let dashboardToken = localStorage.getItem('dashboard_token')
      let dashboardUUID = localStorage.getItem('dashboard_uuid')

      let config = this.$_.merge({}, { uuid: dashboardUUID, id: this.selectedPanel.id })
      let params = { token: dashboardToken }

      this.dashboardService.fetchExportedDashboardPanels(config, params)
        .then((panel) => {
          this.setDashboardPanel(panel)
          loader.hide()
        })
    },
    onSaveDashboardPanel () {
      this.isEditingDashboard = false
      let widgetLayots = {}

      this.$_.forEach(this.layout, (item) => {
        widgetLayots[item.i] = {
          h: item.h,
          w: item.w,
          x: item.x,
          y: item.y,
          type: item.type
        }
      })

      let params = {
        widget_layouts: widgetLayots
      }
      let config = { orgId: this.currentUser.org.id, dashboardId: this.selectedDashboard.id, id: this.selectedPanel.id }
      this.dashboardService.updateDashboardPanel(config, params)
        .then((_) => {
          this.toastr.success('Dashboard saved successfully', 'Success', { closeButton: true, closeDuration: 0 })
        })
        .catch((error) => {
          this.toastr.error(error.title, 'Error', { closeButton: true, closeDuration: 0 })
        })
    },
    onCancelEditDashboard () {
      this.isEditingDashboard = false
    },
    updateDashboardPanel (item) {
      let widgetLayots = this.selectedPanel.widget_layouts
      delete widgetLayots[item.i]

      let params = { widget_layouts: widgetLayots }
      let config = { orgId: this.currentUser.org.id, dashboardId: this.selectedDashboard.id, id: this.selectedPanel.id }
      this.dashboardService.updateDashboardPanel(config, params)
        .then((response) => {
          this.loadDashboardPanel(this.selectedPanel)
        })
    },
    reloadSelectedDasbhoard () {
      let config = { orgId: this.currentUser.org.id, id: this.selectedDashboard.id }
      this.$emit('reload-selected-dashboard-read-id', config)
    },
    savePanelRealtimeHistoricalSettings (params) {
      if (this.dashboardType === 'userDashboard') {
        let config = { orgId: this.selectedDashboard.org_id, dashboardId: this.selectedDashboard.id, id: this.selectedPanel.id }
        this.dashboardService.updateDashboardPanel(config, params)
          .then((response) => {
            this.loadDashboardPanel(this.selectedPanel, true)
          })
      } else {
        this.loadExportedDashboardPanel()
      }
    },
    getWidgetId (item) {
      return this.widgetObject[item.i].widget_id
    },
    getWidgetInstanceId (item) {
      return this.widgetObject[item.i].id
    },
    onDeleteWidgetInstance (id) {
      this.layout = this.$_.filter(this.layout, (item) => {
        return parseInt(item.i) !== id
      })
    },
    captureDashboard () {
      let element = document.getElementById('screenshot-wrap')

      html2canvas(element).then(function (canvas) {
        // Export canvas as a blob
        canvas.toBlob(function (blob) {
        // Generate file download
          saveAs(blob, 'blank_template.png')
        })
      })
    },
    resizeHighchartWidget (item) {
      if (this.$_.includes(['highcharts', 'stock_chart'], item.type)) {
        let ref = 'widget' + this.getWidgetInstanceId(item)
        this.$refs[ref][0].resizeWidget(item)
      }
    },
    createSocket () {
      this.socket = new Socket(socketUrl, { params: { token: this.dashboardSocketToken } })
      this.socket.connect()
      if (this.selectedPanel) {
        this.createPanelChannel(this.selectedPanel.id)
      }
    },
    createPanelChannel (panelId) {
      if (this.channel) {
        this.channel.off()
      }
      this.channel = this.socket.channel('panels:' + panelId, {})
      this.channel.join()
        .receive('ok', resp => { })
        .receive('error', resp => { })
      this.channel.on('out_put_res', payload => {
        let widgetInstance = payload
        let widgetLayouts = widgetInstance.panel.widget_layouts
        delete widgetInstance.panel
        let widgets = this.$_.concat([], this.selectedPanel.widgets, widgetInstance)

        let panel = this.$_.merge({}, this.selectedPanel, {
          widgets: widgets,
          widget_layouts: widgetLayouts
        })

        // this.setPanel(panel)
        this.$emit('set-panel', panel)
        this.widgetObject[widgetInstance.id] = widgetInstance
        this.layout = this.$_.concat(this.layout, this.$_.merge(panel.widget_layouts[widgetInstance.id], {
          i: widgetInstance.id,
          key: this.getUniqueKey()
        }))
      })
    },
    reloadDashboardPanel (panel, joinChannel = true) {
      this.loadDashboardPanel(panel, true)
      if (!this.viewMode && joinChannel) {
        if (this.socket) {
          this.createPanelChannel(panel.id)
        } else {
          this.createSocket()
        }
      }
    }
  },
  mounted () {
    if (!this.viewMode) {
      this.createSocket()
    }

    dasbhoardEventBus.$on('load-dashboard', (dashboard) => {
      this.$emit('load-dashboard', dashboard)
    })
    dasbhoardEventBus.$on('update-dashboard', (dashboard) => {
      this.$emit('update-dashboard', dashboard)
    })

    dasbhoardEventBus.$on('reload-dashboard', () => {
      this.reloadSelectedDasbhoard()
    })
    dasbhoardEventBus.$on('reload-dashboards', () => {
      this.$emit('reload-dashboards')
    })

    dasbhoardEventBus.$on('set-dashboard', (dashboard) => {
      this.$emit('set-dashboard', dashboard)
    })
    dasbhoardEventBus.$on('copy-text', (copyText) => {
      this.$emit('copy-text', copyText)
    })
    dasbhoardEventBus.$on('set-compare-tree-data', (flag) => {
      this.$emit('set-compare-tree-data', flag)
    })

    dasbhoardEventBus.$on('reload-dashboard-panel', (joinChannel = false) => {
      this.loadDashboardPanel(this.selectedPanel, true)
      if (!this.viewMode && joinChannel) {
        if (this.socket) {
          this.createPanelChannel(this.selectedPanel.id)
        } else {
          this.createSocket()
        }
      }
    })
  },
  beforeDestroy () {
    if (this.socket) {
      this.socket.disconnect()
    }
    dasbhoardEventBus.$off()
  }
}
</script>

<style lang="scss" scoped>
  .theme-container {
    display: flex;
    height: 100%;
    .content-wrap {
      width: 100%;
      overflow: auto;
      background-color: #ffffff;
      position: relative;
      height: 100%;
      .widgets-wrap {
        width: 100%;
        height: calc(100% - 70px);
        padding: 8px 5px;
        overflow: auto;
        background-color: #f8f8f8;
        .layout-container {
          width: 2400px;
          height: 2400px;
        }
        .vue-grid-layout {
          .vue-grid-item {
            background-color: white;
            box-shadow: 0 0.75rem 1.5rem rgba(18, 38, 63, 0.03);
            touch-action: none;
            overflow: hidden;
            touch-action: none;
            border-radius: 4px;
            padding: 10px;
            &:hover {
              .header {
                .actions {
                  .icon {
                    opacity: 1;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  .btn.back-btn {
    margin-bottom: 20px;
    width: 105px;
    height: 10px;
    display: flex;
    align-items: center;
  }
</style>

<style lang="scss">
  .select-wrap {
    label {
      text-transform: capitalize;
      font-size: 14px;
      color: #6D6E71;
    }
  }
  .hamburger-action{
    button{
      padding: 0 !important;
      background-color: transparent !important;
      .hamburger{
        width: 35px;
        height: 35px;
        fill: #000;
      }
    }
    .b-dropdown .dropdown-toggle::after{
      display: none !important;
    }
    .dropdown-item{
      padding: 5px 10px !important;
    }
    .dropdown-menu.show{
      left: -160px !important;
      top: 0px !important;
      height: 200px;
      overflow: auto;
    }
  }
  .splitpanes--vertical > .splitpanes__splitter{
    border: 5px solid #2a3042 !important;
  }
  .vue-grid-item.vue-grid-placeholder {
    background: transparent !important;
  }
</style>

<style lang="scss">
.splitpanes {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  width: 100%;
  height: 100%;
}
.splitpanes--vertical {
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-direction: row;
  flex-direction: row;
}
.splitpanes--horizontal {
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
}
.splitpanes--dragging * {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.splitpanes__pane {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.splitpanes--vertical .splitpanes__pane {
  -webkit-transition: width 0.2s ease-out;
  transition: width 0.2s ease-out;
}
.splitpanes--horizontal .splitpanes__pane {
  -webkit-transition: height 0.2s ease-out;
  transition: height 0.2s ease-out;
}
.splitpanes--dragging .splitpanes__pane {
  -webkit-transition: none;
  transition: none;
}
.splitpanes__splitter {
  -ms-touch-action: none;
  touch-action: none;
}
.splitpanes--vertical > .splitpanes__splitter {
  min-width: 1px;
  cursor: col-resize;
}
.splitpanes--horizontal > .splitpanes__splitter {
  min-height: 1px;
  cursor: row-resize;
}
.splitpanes.default-theme .splitpanes__pane {
  background-color: #f2f2f2;
}
.splitpanes.default-theme .splitpanes__splitter {
  background-color: #fff;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: relative;
  -ms-flex-negative: 0;
  flex-shrink: 0;
}
.splitpanes.default-theme .splitpanes__splitter:after,
.splitpanes.default-theme .splitpanes__splitter:before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background-color: rgba(0, 0, 0, 0.15);
  -webkit-transition: background-color 0.3s;
  transition: background-color 0.3s;
}
.splitpanes.default-theme .splitpanes__splitter:hover:after,
.splitpanes.default-theme .splitpanes__splitter:hover:before {
  background-color: rgba(0, 0, 0, 0.25);
}
.splitpanes.default-theme .splitpanes__splitter:first-child {
  cursor: auto;
}
.default-theme.splitpanes .splitpanes .splitpanes__splitter {
  z-index: 1;
}
.default-theme.splitpanes--vertical > .splitpanes__splitter,
.default-theme .splitpanes--vertical > .splitpanes__splitter {
  width: 7px;
  border-left: 1px solid #eee;
  margin-left: -1px;
}
.default-theme.splitpanes--vertical > .splitpanes__splitter:after,
.default-theme .splitpanes--vertical > .splitpanes__splitter:after,
.default-theme.splitpanes--vertical > .splitpanes__splitter:before,
.default-theme .splitpanes--vertical > .splitpanes__splitter:before {
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  width: 1px;
  height: 30px;
}
.default-theme.splitpanes--vertical > .splitpanes__splitter:before,
.default-theme .splitpanes--vertical > .splitpanes__splitter:before {
  margin-left: -2px;
}
.default-theme.splitpanes--vertical > .splitpanes__splitter:after,
.default-theme .splitpanes--vertical > .splitpanes__splitter:after {
  margin-left: 1px;
}
.default-theme.splitpanes--horizontal > .splitpanes__splitter,
.default-theme .splitpanes--horizontal > .splitpanes__splitter {
  height: 7px;
  border-top: 1px solid #eee;
  margin-top: -1px;
}
.default-theme.splitpanes--horizontal > .splitpanes__splitter:after,
.default-theme .splitpanes--horizontal > .splitpanes__splitter:after,
.default-theme.splitpanes--horizontal > .splitpanes__splitter:before,
.default-theme .splitpanes--horizontal > .splitpanes__splitter:before {
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
  width: 30px;
  height: 1px;
}
.default-theme.splitpanes--horizontal > .splitpanes__splitter:before,
.default-theme .splitpanes--horizontal > .splitpanes__splitter:before {
  margin-top: -2px;
}
.default-theme.splitpanes--horizontal > .splitpanes__splitter:after,
.default-theme .splitpanes--horizontal > .splitpanes__splitter:after {
  margin-top: 1px;
}

</style>
