<template>
  <div>
    <v-card>
      <v-card-title>
        <v-select
          :items="pickLists.listViews"
          item-text="name"
          item-value="id"
          :label="lt('DataListView')"
        >
        </v-select>
        <v-spacer></v-spacer
        ><v-btn @click="editListView">
          <v-icon>fa-filter</v-icon>
        </v-btn>
      </v-card-title>

      <!-- WIDE TABLE VIEW -->
      <template v-if="!narrowFormat">
        <v-data-table
          :headers="headers"
          :items="records"
          v-model="selected"
          :options.sync="dataTablePagingOptions"
          :server-items-length="totalRecords"
          :loading="loading"
          :disable-sort="true"
          :show-select="showSelect"
          :single-select="singleSelect"
          :hide-default-header="narrowFormat"
          :footer-props="{
            showCurrentPage: true,
            showFirstLastPage: true,
            itemsPerPageOptions: rowsPerPageItems,
            itemsPerPageText: lt('RowsPerPage'),
            pageText: lt('PageOfPageText')
          }"
          :loading-text="lt('Loading')"
          :no-data-text="lt('NoData')"
          class="elevation-1"
        >
          <template v-slot:body="{ items }">
            <tbody>
              <tr v-for="item in items" :key="item.id">
                <template v-if="showSelect">
                  <td>
                    <v-checkbox
                      v-model="selected"
                      :value="item"
                      primary
                      hide-details
                    ></v-checkbox>
                  </td>
                </template>
                <td v-for="c in item.columns" :key="c.key">
                  <template v-if="c.t == 1">
                    <!-- DATETIME -->
                    {{ c.v }}
                  </template>
                  <template v-else-if="c.t == 2">
                    <!-- DATE -->
                    {{ c.v }}
                  </template>
                  <template v-else-if="c.t == 3">
                    <!-- TIME -->
                    {{ c.v }}
                  </template>
                  <template v-else-if="c.t == 4">
                    <!-- TEXT (also maybe openable)-->
                    <template v-if="c.i">
                      <!-- openable object with an ID -->
                      <v-btn depressed small @click="btnClick(c.key, c.i)">{{
                        c.v
                      }}</v-btn>
                    </template>
                    <template v-else>
                      {{ c.v }}
                    </template>
                  </template>
                  <template v-else-if="c.t == 5">
                    <!-- INTEGER -->
                    {{ c.v }}
                  </template>
                  <template v-else-if="c.t == 6">
                    <!-- BOOL -->
                    <div class="text-center">
                      <v-icon v-if="c.v === false" small>far fa-square</v-icon>
                      <v-icon v-else-if="c.v === true" small
                        >far fa-check-square</v-icon
                      >
                      <v-icon v-else small>far fa-minus-square</v-icon>
                    </div>
                  </template>
                  <template v-else-if="c.t == 7">
                    <!-- DECIMAL -->
                    {{ c.v }}
                  </template>
                  <template v-else-if="c.t == 8">
                    <!-- CURRENCY -->
                    <div class="text-right">{{ c.v }}</div>
                  </template>
                  <template v-else-if="c.t == 9">
                    <!-- TAGS -->
                    {{ c.v }}
                  </template>
                  <template v-else-if="c.t == 10">
                    <!-- ENUM (translated to text on getdata) -->
                    {{ c.v }}
                  </template>
                  <template v-else-if="c.t == 11">
                    <!-- EMAIL -->
                    <a :href="'mailto:' + c.v">{{ c.v }}</a>
                  </template>
                  <template v-else-if="c.t == 12">
                    <!-- URL / HTTP -->
                    <!-- Expects full url with protocol etc in c.v so might need to add to record builder -->
                    <a :href="c.v" target="_blank">{{ c.v }}</a>
                  </template>
                  <template v-else>
                    <!-- UNKNOWN -->
                    {{ c.v }}
                  </template>
                </td>
              </tr>
            </tbody>
          </template>
        </v-data-table>
      </template>
      <!-- MOBILE TABLE VIEW -->
      <template v-else>
        <v-data-iterator
          :headers="headers"
          :items="records"
          v-model="selected"
          :options.sync="dataTablePagingOptions"
          :server-items-length="totalRecords"
          :loading="loading"
          :disable-sort="true"
          :show-select="showSelect"
          :single-select="singleSelect"
          :hide-default-header="narrowFormat"
          :footer-props="{
            showCurrentPage: true,
            showFirstLastPage: true,
            itemsPerPageOptions: rowsPerPageItems,
            itemsPerPageText: lt('RowsPerPage'),
            pageText: lt('PageOfPageText')
          }"
          :loading-text="lt('Loading')"
          :no-data-text="lt('NoData')"
          class="elevation-1"
        >
          <template v-slot:header="props">
            <!-- Mimic the full width data table select all toggle -->
            <div
              @click="props.toggleSelectAll(!props.everyItem)"
              class="pl-2 pt-2"
            >
              <v-icon v-if="!props.someItems" large>far fa-square</v-icon>
              <v-icon v-if="props.someItems && !props.everyItem" large
                >far fa-minus-square</v-icon
              >
              <v-icon v-if="props.everyItem" large>far fa-check-square</v-icon>
            </div>
          </template>

          <template v-slot:default="{ items }">
            <v-row>
              <v-col
                v-for="item in items"
                :key="item.id"
                cols="12"
                sm="6"
                md="4"
                lg="3"
              >
                <v-card elevation="4" tile>
                  <template v-if="showSelect">
                    <v-card-title class="subheading font-weight-bold">
                      <v-checkbox
                        v-model="selected"
                        :value="item"
                        primary
                        hide-details
                      ></v-checkbox>
                    </v-card-title>
                    <v-divider></v-divider>
                  </template>
                  <v-list dense>
                    <v-list-item
                      two-line
                      v-for="c in item.columns"
                      :key="c.key"
                    >
                      <v-list-item-content>
                        <v-list-item-title>
                          {{ getHeaderText(c.key) }}</v-list-item-title
                        >
                        <v-list-item-subtitle>
                          <template v-if="c.t == 1">
                            <!-- DATETIME -->
                            {{ c.v }}
                          </template>
                          <template v-else-if="c.t == 2">
                            <!-- DATE -->
                            {{ c.v }}
                          </template>
                          <template v-else-if="c.t == 3">
                            <!-- TIME -->
                            {{ c.v }}
                          </template>
                          <template v-else-if="c.t == 4">
                            <!-- TEXT (also maybe openable)-->
                            <template v-if="c.i">
                              <!-- openable object with an ID -->
                              <span
                                @click="btnClick(c.key, c.i)"
                                class="primary--text subtitle-1 font-weight-bold"
                                style="cursor:pointer"
                                >{{ c.v }}
                              </span>
                            </template>
                            <template v-else>
                              {{ c.v }}
                            </template>
                          </template>
                          <template v-else-if="c.t == 5">
                            <!-- INTEGER -->
                            {{ c.v }}
                          </template>
                          <template v-else-if="c.t == 6">
                            <!-- BOOL -->
                            <div>
                              <v-icon v-if="c.v === false" small
                                >far fa-square</v-icon
                              >
                              <v-icon v-else-if="c.v === true" small
                                >far fa-check-square</v-icon
                              >
                              <v-icon v-else small>far fa-minus-square</v-icon>
                            </div>
                          </template>
                          <template v-else-if="c.t == 7">
                            <!-- DECIMAL -->
                            {{ c.v }}
                          </template>
                          <template v-else-if="c.t == 8">
                            <!-- CURRENCY -->
                            <div>{{ c.v }}</div>
                          </template>
                          <template v-else-if="c.t == 9">
                            <!-- TAGS -->
                            {{ c.v }}
                          </template>
                          <template v-else-if="c.t == 10">
                            <!-- ENUM (translated to text on getdata) -->
                            {{ c.v }}
                          </template>
                          <template v-else-if="c.t == 11">
                            <!-- EMAIL -->
                            <a :href="'mailto:' + c.v">{{ c.v }}</a>
                          </template>
                          <template v-else-if="c.t == 12">
                            <!-- URL / HTTP -->
                            <!-- Expects full url with protocol etc in c.v so might need to add to record builder -->
                            <a :href="c.v" target="_blank">{{ c.v }}</a>
                          </template>
                          <template v-else>
                            <!-- UNKNOWN -->
                            {{ c.v }}
                          </template>
                        </v-list-item-subtitle>
                      </v-list-item-content>
                    </v-list-item>
                  </v-list>
                </v-card>
              </v-col>
            </v-row>
          </template>
        </v-data-iterator>
      </template>
    </v-card>
  </div>
</template>

<script>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*  Xeslint-disable    */
////////////////////////////////////////////////////////////////////////////////////////////////////////////
export default {
  data() {
    return {
      loading: true,
      dataTablePagingOptions: {},
      listViewId: 0,
      pickLists: {
        listViews: []
      },
      headers: [],
      serverColumns: [],
      totalRecords: 0,
      records: [],
      rowsPerPageItems: [5, 10, 25, 50, 100],
      selected: [],
      narrowFormat: false
    };
  },
  props: {
    apiBaseUrl: {
      type: String,
      default: "DataList"
    },
    formKey: String,
    dataListKey: String,
    dataListSort: String,
    dataListFilter: String,
    showSelect: {
      type: Boolean,
      default: false
    },
    singleSelect: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    dataTablePagingOptions: {
      handler() {
        this.getDataFromApi();
      },
      deep: true
    },
    selected: function(newValue, oldValue) {
      if (newValue.length != oldValue.length) {
        this.handleSelectChange();
      }
    },
    "$vuetify.breakpoint.xs": function(value) {
      this.narrowFormat = value;
    }
  },
  methods: {
    //Used by narrow view to get the "header" text for a column based on the column key
    getHeaderText(key) {
      //key format is row-column e.g."500-2"
      var columnIndex = key.split("-")[1];
      var header = this.headers[columnIndex - 1];
      if (header && header.text) {
        return header.text;
      }
      return "";
    },
    handleSelectChange() {
      //due to making own template for items need to handle singleselect which only affects if select all checkbox at top is visible when making own item template
      if (this.singleSelect) {
        this.selected.splice(0, this.selected.length - 1);
      }
      //emit event to parent form of selected rows
      //this.$emit("update:selected", this.selected);
      //Note that this bubbles up all the columns of all the selected rows

      //so, to be more efficient for now will just send the ID's until I see a need for other shit
      this.$emit("update:selected", window.$gz._.map(this.selected, "id"));
    },
    editListView() {
      //  path: "/ay-data-list-view/:listViewId/:dataListKey",
      this.$router.push({
        name: "ay-data-list-view",
        params: {
          listViewId: this.listViewId,
          dataListKey: this.dataListKey
        }
      });
    },

    btnClick(key, i) {
      //translate key to actual object type from header data
      //key format is row-column e.g."500-2"
      //get the datatype of the column which matches the server columns array index
      var typeToOpen = this.serverColumns[key.split("-")[1]].ay;

      //i is the actual AyaNova index of that record so we have all we need to open that object
      window.$gz.eventBus.$emit("openobject", { type: typeToOpen, id: i });
    },
    lt(ltKey) {
      return window.$gz.locale.get(ltKey);
    },

    getDataFromApi() {
      var that = this;

      //start with defaults
      var listOptions = {
        DataListKey: that.dataListKey,
        Limit: 5,
        Offset: 0
      };
      //calculate paging based on settings
      const { page, itemsPerPage } = that.dataTablePagingOptions;
      if (itemsPerPage && itemsPerPage > 0) {
        listOptions.Offset = (page - 1) * itemsPerPage;
        listOptions.Limit = itemsPerPage;
      }

      //is there a filter?
      if (that.dataFilterId != 0) {
        listOptions["DataFilterID"] = that.dataFilterId;
      }

      that.loading = true;

      // {
      //   "offset": 0,
      //   "limit": 0,
      //   "mini": true,
      //   "dataListKey": "string",
      //   "filterJson": "string",
      //   "sortJson": "string"
      // }

      window.$gz.api
        .upsert(that.apiBaseUrl, {
          offset: listOptions.Offset,
          limit: listOptions.Limit,
          dataListKey: that.dataListKey,
          listView: ""
        })
        .then(res => {
          //NOTE: This is how to call an async function and await it from sync code
          (async function() {
            //Save a copy of the server columns data for handling button clicks etc later
            that.serverColumns = res.columns;
            //Make sure the locale keys are fetched
            await fetchLocalizedHeaderNames(res.columns); //Note can use await here because it's wrapped inside an async function call, it will wait then resume next stuff below
            await fetchEnums(res.columns);
            //build that.headers here
            that.headers = buildHeaders(res.columns);
            //Post process data here and then set that.records
            that.records = buildRecords(res.data, res.columns);
            that.loading = false;
            that.totalRecords = res.totalRecordCount;

            //persist the paging options so user sees same page and list on refresh or leave and return scenario

            window.$gz.form.setFormSettings(that.formKey, {
              temp: { page: that.dataTablePagingOptions.page },
              saved: {
                itemsPerPage: that.dataTablePagingOptions.itemsPerPage
              }
            });
            //////////
          })();
        });
    }
  },
  created() {
    //rehydrate last form settings
    var formSettings = window.$gz.form.getFormSettings(this.formKey);
    if (formSettings.saved && formSettings.saved.itemsPerPage) {
      this.dataTablePagingOptions.itemsPerPage =
        formSettings.saved.itemsPerPage;
    }
    if (formSettings.temp && formSettings.temp.page) {
      this.dataTablePagingOptions.page = formSettings.temp.page;
    }
  }
};

//Called by getDataFromApi on retrieval of list with columnData
function buildHeaders(columnData) {
  //debugger;
  //iterate columns, build headers and return
  if (!columnData) {
    return [];
  }
  var ret = [];
  //iterate the columns, skip over the first one as it's the df column and not for display
  for (var i = 1; i < columnData.length; i++) {
    var cm = columnData[i];
    var h = {};
    h.text = window.$gz.locale.get(cm.cm);
    h.value = "columns.c" + i.toString(); //+".v";
    ret.push(h);
  }

  return ret;
}

//Called by getDataFromApi on retrieval of list with columnData
function buildRecords(listData, columndefinitions) {
  //iterate data, build each object keyed with index name and display set to correct locale filter and then return
  if (!listData) {
    return;
  }
  var ret = [];

  //cache display format stuff
  var timeZoneName = window.$gz.locale.getTimeZoneName();
  var languageName = window.$gz.locale.getBrowserLanguages();
  var hour12 = window.$gz.store.state.locale.hour12;
  var currencyName = window.$gz.store.state.locale.currencyName;

  //comes as an array of arrays, needs to leave as an array of objects representing each row
  for (var iRow = 0; iRow < listData.length; iRow++) {
    var row = listData[iRow];
    //iterate row and build object representing row data keyed to index
    //first column is the default column which sets the id for the row
    var o = { id: row[0].v, columns: {} };
    for (var iColumn = 1; iColumn < row.length; iColumn++) {
      var column = row[iColumn];

      var dataType = columndefinitions[iColumn].dt;
      var display = column.v;
      switch (dataType) {
        case 1: //datetime format to shortdatetime
          display = window.$gz.locale.utcDateToShortDateAndTimeLocalized(
            display,
            timeZoneName,
            languageName,
            hour12
          );
          break;
        case 2: //date only
          display = window.$gz.locale.utcDateToShortDateLocalized(
            display,
            timeZoneName,
            languageName
          );
          break;
        case 3: //time only
          display = window.$gz.locale.utcDateToShortTimeLocalized(
            display,
            timeZoneName,
            languageName,
            hour12
          );
          break;
        case 7: //decimal
          display = window.$gz.locale.decimalLocalized(display, languageName);
          break;
        case 8: //currency
          display = window.$gz.locale.currencyLocalized(
            display,
            languageName,
            currencyName
          );
          break;
        case 10: //enum
          display = window.$gz.enums.get(
            columndefinitions[iColumn].et,
            display
          );
          break;
        default:
        //do nothing, allow it to stay as is (checkbox, plain text etc)
      }
      //build the row column object that will be used by the datatable
      var columnObject = {
        v: display,
        t: dataType,
        key: iRow + "-" + iColumn
      };
      //is the source dtalist field openable?  If so it will have an i property set for it's ID and we already know the types to open from the column headers data
      //so between the two we can make a clickable button in the grid that triggers a function with the column index and the id and that in turn will bubble up the event to open that
      //object
      if (column.i) {
        columnObject["i"] = column.i;
      }
      o.columns["c" + iColumn.toString()] = columnObject;
      //Is:
      //Headers: [ { "text": "Name", "value": "c1" }, { "text": "Serial #", "value": "c2" },
      //Records: [ { "id": 1, "c1": "Incredible Metal Fish 76", "c2": 1, "c3": "$877.8", "c4": "AuthorizationRoles.65536", "c5": "2020-01-30 01:53:57 AM", "c6": "Yup", "c7": "Virgil Strosin 74" }, { "id": 2, "c1": "Practical Plastic Bike 77", "c2": 2, "
      //CHANGE TO:
      //Headers: [ { "text": "Name", "value": "c1.v" }, { "text": "Serial #", "value": "c2" },
      //Records: [ { "id": 1,columns: {"c1": {v:"Incredible Metal Fish 76",t:THETYPE,key:ROWID-COLUMNID e.g. 1-1,1-2,2-1 etc}, "c2": 1, "c3": "$877.8", "c4": "AuthorizationRoles.65536", "c5": "2020-01-30 01:53:57 AM", "c6": "Yup", "c7": "Virgil Strosin 74" }, { "id": 2, "c1": "Practical Plastic Bike 77", "c2": 2, "
      //THis way can have v-if for each column that changes based on type and then has it's shit figured out
    }
    ret.push(o);
  }
  return ret;
}

//////////////////////////////////////////////////////////
//
// Ensures column names are present in locale table
//
async function fetchLocalizedHeaderNames(columnData) {
  if (!columnData) {
    return;
  }
  var headerKeys = [];
  for (var i = 1; i < columnData.length; i++) {
    var cm = columnData[i];
    headerKeys.push(cm.cm);
  }
  //Now fetch all the keys and await the response before returning
  await window.$gz.locale
    .fetch(headerKeys)
    .then(() => {
      return;
    })
    .catch(err => {
      that.formState.ready = true; //show the form anyway so we know what's what
      window.$gz.errorHandler.handleFormError(err);
    });
}

//////////////////////////////////////////////////////////
//
// Ensures column enums are present in enums list in store
//
async function fetchEnums(columnData) {
  if (!columnData) {
    return;
  }
  var headerKeys = [];
  for (var i = 1; i < columnData.length; i++) {
    var cm = columnData[i];
    if (cm.et) {
      await window.$gz.enums.fetchEnumList(cm.et);
    }
  }
}
</script>
