<template>
  <v-container fluid class="h-100 d-100" style="overflow: auto">
    <kanban-board
      :stages="kanban.groupingColumnItems"
      :blocks="kanban.blocks"
      class="h-100 my-0 mx-n2"
      @update-block="updateBlock"
    >
      <div v-for="stage in kanban.groupingColumnItems" :slot="stage" :key="stage" class="mx-auto">
        <enum-cell :value="stage" :column="groupingFieldColumn" />
      </div>
      <div v-for="block in kanban.blocks" :slot="block.id" :key="block.c_pk" class="caption">
        <v-hover v-slot="{ hover }">
          <v-card class="h-100" :elevation="hover ? 4 : 1" @click="$emit('expandKanbanForm', { rowIdx: block.c_pk })">
            <v-card-text>
              <v-container>
                <v-row class="">
                  <v-col
                    v-for="col in fields"
                    v-show="showFields[col.title]"
                    :key="col.title"
                    class="kanban-col col-12"
                  >
                    <label :for="`data-table-form-${col.title}`" class="body-2 text-capitalize caption grey--text">
                      <virtual-header-cell
                        v-if="col.virtual"
                        :column="col"
                        :nodes="nodes"
                        :is-form="true"
                        :meta="meta"
                      />
                      <header-cell v-else :is-form="true" :value="col.title" :column="col" />
                    </label>
                    <virtual-cell
                      v-if="col.virtual"
                      ref="virtual"
                      :column="col"
                      :row="block"
                      :nodes="nodes"
                      :meta="meta"
                    />
                    <table-cell
                      v-else
                      :value="block[col.title]"
                      :column="col"
                      :sql-ui="sqlUi"
                      class="xc-input body-2"
                      :meta="meta"
                    />
                  </v-col>
                </v-row>
              </v-container>
            </v-card-text>
          </v-card>
        </v-hover>
      </div>
      <div v-for="stage in kanban.groupingColumnItems" :key="stage" :slot="`footer-${stage}`" class="kanban-footer">
        <x-btn
          v-if="stage"
          outlined
          tooltip="Add a new record"
          color="primary"
          class="primary"
          x-small
          fab
          @click="insertNewRow(true, true, { [groupingField]: stage })"
        >
          <v-icon small> mdi-plus </v-icon>
        </x-btn>
        <!-- <x-btn
          v-else
          outlined
          tooltip="New Stack"
          color="primary"
          class="primary"
          small
          @click="insertNewRow(true, true, {[groupingField]: stage})"
        >
          <v-icon small left>
            mdi-plus
          </v-icon>
            New Stack
        </x-btn> -->
        <div class="record-cnt caption grey--text">
          {{ kanban.recordCnt[stage] }} / {{ kanban.recordTotalCnt[stage] }}
          {{ kanban.recordTotalCnt[stage] > 1 ? 'records' : 'record' }}
        </div>
      </div>
    </kanban-board>
  </v-container>
</template>

<script>
import VirtualHeaderCell from '../components/VirtualHeaderCell';
import HeaderCell from '../components/HeaderCell';
import VirtualCell from '../components/VirtualCell';
import TableCell from '../components/Cell';
import EnumCell from '../components/cell/EnumCell';
export default {
  name: 'KanbanView',
  components: { TableCell, VirtualCell, HeaderCell, VirtualHeaderCell, EnumCell },
  props: [
    'nodes',
    'table',
    'showFields',
    'availableColumns',
    'meta',
    'kanban',
    'primaryValueColumn',
    'showSystemFields',
    'sqlUi',
    'groupingField',
    'api',
  ],
  computed: {
    fields() {
      if (this.availableColumns) {
        return this.availableColumns;
      }
      if (this.showSystemFields) {
        return this.meta.columns || [];
      }
      const hideCols = ['created_at', 'updated_at'];
      return (
        this.meta.columns.filter(
          c =>
            !(c.pk && c.ai) &&
            !hideCols.includes(c.column_name) &&
            !(this.meta.v || []).some(v => v.bt && v.bt.column_name === c.column_name)
        ) || []
      );
    },
    groupingFieldColumn() {
      return this.fields.filter(f => f.title === this.groupingField)[0];
    },
  },
  mounted() {
    const kbListElements = document.querySelectorAll('.drag-inner-list');
    kbListElements.forEach(kbListEle => {
      kbListEle.addEventListener('scroll', async e => {
        if (kbListEle.scrollTop + kbListEle.clientHeight >= kbListEle.scrollHeight) {
          const groupingFieldVal = kbListEle.getAttribute('data-status');
          this.$emit('loadMoreKanbanData', groupingFieldVal);
        }
      });
    });
  },
  methods: {
    async updateBlock(c_pk, status) {
      try {
        if (!this.api) {
          this.$toast
            .error('API not found', {
              position: 'bottom-center',
            })
            .goAway(3000);
          return;
        }

        // update kanban block
        const targetBlock = this.kanban.blocks.find(b => b.c_pk === c_pk);
        if (!targetBlock) {
          this.$toast
            .error(`Block with ID ${c_pk} not found`, {
              position: 'bottom-center',
            })
            .goAway(3000);
          return;
        }

        if (targetBlock.status === status) {
          // no change
          return;
        }

        const uncategorized = 'Uncategorized';
        const prevStatus = targetBlock.status;
        await this.api.update(
          c_pk,
          { [this.groupingField]: status === uncategorized ? null : status }, // new data
          { [this.groupingField]: prevStatus }
        ); // old data

        this.$set(targetBlock, 'status', status);
        this.$set(targetBlock, this.groupingField, status === uncategorized ? null : status);

        // update kanban data
        const kanbanRow = this.kanban.data.find(d => d.row.c_pk === c_pk);
        if (kanbanRow) {
          this.$set(kanbanRow.row, this.groupingField, status === uncategorized ? null : status);
        }
        this.$set(this.kanban.recordCnt, prevStatus, this.kanban.recordCnt[prevStatus] - 1);
        this.$set(this.kanban.recordCnt, status, this.kanban.recordCnt[status] + 1);
        this.$set(this.kanban.recordTotalCnt, prevStatus, this.kanban.recordTotalCnt[prevStatus] - 1);
        this.$set(this.kanban.recordTotalCnt, status, this.kanban.recordTotalCnt[status] + 1);
        this.$forceUpdate();
        this.$toast
          .success(`Moved block from ${prevStatus} to ${status ?? uncategorized} successfully.`, {
            position: 'bottom-center',
          })
          .goAway(3000);
      } catch (e) {
        if (e.response && e.response.data && e.response.data.msg) {
          this.$toast
            .error(e.response.data.msg, {
              position: 'bottom-center',
            })
            .goAway(3000);
        } else {
          this.$toast
            .error(`Failed to update block : ${e.message}`, {
              position: 'bottom-center',
            })
            .goAway(3000);
        }
      }
    },
    insertNewRow(atEnd = false, expand = false, presetValues = {}) {
      this.$emit('insertNewRow', atEnd, expand, presetValues);
    },
  },
};
</script>

<style scoped lang="scss">
::v-deep {
  .v-card {
    border: 1px solid rgba(0, 0, 0, 0.2);
  }

  ul.drag-inner-list {
    overflow-y: scroll;
  }

  ul.drag-list,
  ul.drag-inner-list {
    list-style-type: none;
    margin: 0;
    padding: 0;
  }

  .drag-container {
    //max-width: 1000px;
    margin: 20px 0px;
  }

  .drag-list {
    display: flex;
    align-items: flex-start;
  }

  @media (max-width: 690px) {
    .drag-list {
      display: block;
    }
  }

  .drag-column {
    flex: 1;
    margin: 0 10px;
    position: relative;
    background: var(--v-backgroundColor-base); //rgba(256, 256, 256, 0.2);
    border-radius: 6px;
    max-width: 240px;
  }

  .drag-column-footer {
    padding: 20px 10px 10px 10px;
    text-align: center;
  }

  /*  .drag-column-footer .v-btn {
    border-radius: 50%;
    border: 2px solid;
    padding: 0px 0px 0px 6px;
    min-width: 40px;
    min-height: 38px;
  }*/

  .drag-column-footer .record-cnt {
    height: 38px;
    line-height: 38px;
    font-size: 15px;
  }

  .drag-column-footer .v-btn .mdi-plug::before {
    font-weight: bold;
  }

  @media (max-width: 690px) {
    .drag-column {
      margin-bottom: 30px;
    }
  }

  .drag-column h2 {
    font-size: 0.8rem;
    margin: 0;
    text-transform: uppercase;
    font-weight: 600;
  }

  .drag-column-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 240px;
  }

  .drag-column-header .set-item {
    margin-top: 20px !important;
  }

  .drag-item {
    margin: 10px;
    background: var(--v-backgroundColor-lighten2);
    transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
    border-radius: 4px;
  }

  .drag-item .container {
    padding: 0px;
  }

  .drag-item.is-moving {
    transform: scale(1.1);
    background: var(--v-backgroundColor-darken1);
  }

  .drag-header-more {
    cursor: pointer;
  }

  .drag-options {
    left: 0;
    width: 100%;
    height: 100%;
    transform: translateX(100%);
    opacity: 0;
    transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
  }

  .drag-options.active {
    transform: translateX(0);
    opacity: 1;
  }

  .drag-options-label {
    display: block;
    margin: 0 0 5px 0;
  }

  .drag-options-label input {
    opacity: 0.6;
  }

  .drag-options-label span {
    display: inline-block;
    font-size: 0.9rem;
    font-weight: 400;
    margin-left: 5px;
  }

  /* Dragula CSS  */
  .gu-mirror {
    position: fixed !important;
    margin: 0 !important;
    z-index: 9999 !important;
    opacity: 0.8;
    list-style-type: none;
  }

  .gu-hide {
    display: none !important;
  }

  .gu-unselectable {
    -webkit-user-select: none !important;
    -moz-user-select: none !important;
    -ms-user-select: none !important;
    user-select: none !important;
  }

  .gu-transit {
    opacity: 0.2;
  }

  .kanban-col {
    padding: 10px;
  }

  .drag-container {
    display: inline-block;
    .drag-list {
      height: 100%;
      display: inline-flex;

      .drag-column {
        display: flex;
        flex-direction: column;
        max-height: max(400px, 100%);

        .drag-inner-list {
          overflow-y: auto;
          overflow-x: hidden;
          min-height: 200px;
          flex-grow: 1;
        }
      }
    }
  }
}
</style>

<!--
/**
 * @copyright Copyright (c) 2021, Xgene Cloud Ltd
 *
 * @author Wing-Kam Wong <wingkwong.code@gmail.com>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
-->
