import { Component, h, Host, Method, Watch, Event, State, Prop } from '@stencil/core';
import { format, isToday, isYesterday, isSameDay } from 'date-fns';
import { cloneDeep } from 'lodash.clonedeep';
export class GdUserDashboard {
  constructor() {
    /**
     * dashboard list items
     */
    this.items = null;
    /**
     * a list of tags to show in the filter by dropdown
     */
    this.tags = [];
    /**
     * whether to split the history items by showing date headers
     */
    this.showDateHeaders = true;
    /**
     * if the share as url functionality should be available or not
     */
    this.canShareAsUrl = false;
    /**
     * historyItems: item deep clone
     */
    this.historyItems = null;
    /**
     * the currently visible list
     */
    this.activeList = 'history';
    /**
     * holds the current list of selected history items
     */
    this.selectedHistoryItems = [];
    /**
     * controls when the export dialog shows
     */
    this.showExportDialog = false;
    /**
     * controls when the share dialog shows
     */
    this.showShareDialog = false;
    /**
     * controls when the import dialog shows
     */
    this.showImportDialog = false;
    /**
     * controls when the bulk tag dialog shows
     */
    this.showBulkTagDialog = false;
    /**
     * controls when the datalist import dialog shows
     */
    this.showDatalistImportDialog = false;
  }
  /**
   * an exposed method to change the visible list
   * @param listType
   */
  async setActiveList(listType) {
    if (listType == this.activeList) {
      return;
    }
    this.activeList = listType;
    this.clearFilterByTag();
  }
  /**
   * on load, need to notify the application to load the requested list
   */
  componentDidLoad() {
    this.notifyOfListChange();
    this.handleActiveDatalistChanged();
    this.historyItems = cloneDeep(this.items);
  }
  /**
   * anytime the active list changes, trigger an event to let the user know
   */
  notifyOfListChange() {
    this.activeListChanged.emit(this.activeList);
  }
  handleActiveDatalistChanged() {
    this.showDatalistImportDialog = this.activeDatalist ? true : false;
  }
  handleItemsChanged() {
    // reset selected history items when the list changes
    this.selectedHistoryItems = [];
  }
  appendLeadingZeroes(n) {
    if (n <= 9) {
      return '0' + n;
    }
    return n;
  }
  filterByTag(tag) {
    this.selectedTag = tag;
    this.filterChanged.emit(tag);
  }
  clearFilterByTag() {
    if (!this.filterByEl || !this.selectedTag) {
      return;
    }
    this.filterByEl.shadowRoot.querySelector('select').value = ''; // reset the filter by value
    this.filterByTag(''); // make sure the event is emitted
  }
  clickFilterByTag(tag) {
    if (!this.filterByEl || !this.selectedTag) {
      return;
    }
    this.filterByEl.shadowRoot.querySelector('select').value = tag; // reset the list by tag value
    this.filterByTag(tag); // make sure the event is emitted
  }
  editHistoryItem(historyItem) {
    this.editableHistoryItem = {
      current: historyItem,
      changes: Object.assign({}, historyItem),
    };
  }
  stopEditingHistoryItem() {
    this.editableHistoryItem = undefined;
  }
  saveHistoryItemChanges(historyItem) {
    this.saveHistoryItem.emit(historyItem);
    this.stopEditingHistoryItem();
  }
  selectedItemChanged(item) {
    if (!item.selected) {
      // remove from list of selected items
      this.selectedHistoryItems = [].concat(this.selectedHistoryItems.filter(id => id != item.historyItem.id));
    }
    else if (item.selected && !this.selectedHistoryItems.find(id => id == item.historyItem.id)) {
      // add to list of selected history items
      this.selectedHistoryItems = [].concat(this.selectedHistoryItems, item.historyItem.id);
    }
  }
  openExportDialog() {
    if (this.selectedHistoryItems.length <= 0) {
      return;
    }
    this.showExportDialog = true;
  }
  openBulkTagDialog() {
    if (this.selectedHistoryItems.length <= 0) {
      return;
    }
    this.showBulkTagDialog = true;
  }
  selectAllHistoryItems() {
    this.selectedHistoryItems = [].concat(this.historyItems.map((item) => item.id));
  }
  deselectAllHistoryItems() {
    this.selectedHistoryItems = [];
  }
  confirmAndDeleteHistoryItems(historyItemIds) {
    if (!historyItemIds.length || !confirm(`Are you sure you want to delete these ${historyItemIds.length} items?`)) {
      return;
    }
    this.deleteHistoryItems.emit(historyItemIds);
  }
  bulkAddTags(tagOptions) {
    // compile a list of the modified history items and add the requested tags
    let historyItems = this.historyItems
      .filter(item => tagOptions.historyItemIds.includes(item.id))
      .map(historyItem => {
      if (!historyItem.tags)
        historyItem.tags = [];
      // add tags to history item and remove duplicates (if it already has the entered tag)
      historyItem.tags = [...new Set(historyItem.tags.concat(tagOptions.tags))];
      return historyItem;
    });
    this.updateHistoryItems.emit(historyItems);
  }
  /**
   * renders the user dashboard
   */
  render() {
    var _a, _b, _c;
    return (h(Host, null,
      h("div", { class: "container-fluid pt-5" },
        h("div", { class: "row" },
          h("div", { class: "list-navigation" },
            h("h4", { class: "py-4" }, "My Dashboard"),
            h("bs-nav", { variant: "pills", fill: true, vertical: true, class: "nav" },
              h("bs-nav-item", { href: "javascript:;", onClick: () => this.setActiveList('favorites'), active: this.activeList == 'favorites' },
                h("bs-icon", { icon: "fas fa-heart", class: "mr-2" }),
                "My Favorites"),
              h("bs-nav-item", { href: "javascript:;", onClick: () => this.setActiveList('history'), active: this.activeList == 'history' },
                h("bs-icon", { icon: "fab fa-history", class: "mr-2" }),
                "Site History"),
              h("bs-nav-item", { href: "javascript:;", onClick: () => this.setActiveList('shared'), active: this.activeList == 'shared' },
                h("bs-icon", { icon: "fab fa-share", class: "mr-2" }),
                "Shared"))),
          h("div", { class: "col pt-4" },
            h("div", { class: "d-flex align-items-center" },
              h("bs-button-group", { role: "toolbar", "aria-label": "Bulk actions" },
                h("bs-button-group", { class: "mr-3", "aria-label": "Bulk select/deselect" }, this.selectedHistoryItems.length > 0 ? (h("bs-button", { class: "deselect", variant: "outline-secondary", title: "Deselect all", onClick: this.deselectAllHistoryItems.bind(this) },
                  h("bs-icon", { icon: "fas fa-square", size: 20 }),
                  "\u00A0")) : (h("bs-button", { variant: "outline-secondary", title: "Select all", onClick: this.selectAllHistoryItems.bind(this) },
                  h("bs-icon", { icon: "fas fa-square", size: 20 }),
                  "\u00A0"))),
                h("bs-button-group", { class: "mr-3", "aria-label": "Bulk history actions" },
                  h("bs-button", { variant: "outline-secondary", onClick: () => (this.showImportDialog = true) },
                    h("bs-icon", { icon: "fab fa-file-import", size: 20, class: "mr-2" }),
                    "Import"),
                  h("bs-button", { variant: "outline-secondary", disabled: this.selectedHistoryItems.length <= 0, onClick: () => this.openExportDialog() },
                    h("bs-icon", { icon: "fab fa-file-export", size: 20, class: "mr-2" }),
                    "Export")),
                h("bs-button-group", { class: "mr-3", "aria-label": "Bulk history actions" },
                  h("bs-button", { variant: "outline-secondary", disabled: this.selectedHistoryItems.length <= 0, onClick: () => this.openBulkTagDialog() },
                    h("bs-icon", { icon: "fab fa-tags", size: 20, class: "mr-2" }),
                    "Tag"),
                  h("bs-button", { variant: "outline-secondary", disabled: this.selectedHistoryItems.length <= 0, onClick: () => this.confirmAndDeleteHistoryItems(this.selectedHistoryItems) },
                    h("bs-icon", { icon: "fab fa-trash-alt", size: 20, class: "mr-2" }),
                    "Delete"))),
              h("bs-form-row", { class: "filters" },
                h("bs-form-group", { stack: false },
                  h("bs-form-label", { style: { fontWeight: '600' } }, "Filter By"),
                  h("bs-form-control", { ref: el => (this.filterByEl = el), as: "select", name: "filterByTag", onBsInput: (e) => { var _a, _b; return this.filterByTag((_b = (_a = e.detail) === null || _a === void 0 ? void 0 : _a.target) === null || _b === void 0 ? void 0 : _b.value); } },
                    h("option", { value: "" }, "Select"),
                    this.tags.map(tag => (h("option", { value: tag.tag },
                      tag.tag,
                      " (",
                      tag.count,
                      ")")))),
                  h("bs-button", { class: "ml-1 pr-3", variant: "link", onClick: () => this.clearFilterByTag(), title: "Clear Filter", disabled: !this.selectedTag },
                    h("bs-icon", { icon: "fab fa-times-circle", size: 16, style: { color: '#333' }, class: "anim-scale" }))))),
            h("div", { class: "list-items" },
              h("bs-list-group", { horizontal: "sm", flush: true },
                this.historyItems == null && (h("div", { class: "loading" },
                  h("bs-spinner", { variant: "primary", size: "sm" }),
                  h("div", null,
                    "Loading ",
                    this.activeList,
                    "..."))),
                ((_a = this.historyItems) === null || _a === void 0 ? void 0 : _a.length) == 0 && h("div", null,
                  "You don't have any ",
                  this.activeList,
                  " items yet."), (_b = this.historyItems) === null || _b === void 0 ? void 0 :
                _b.map((item, index, items) => {
                  const renderedItem = (h("gd-user-dashboard-list-item", { key: item.id, item: item, "allow-edit": this.activeList == 'favorites' || this.activeList == 'shared', "show-shared-by": this.activeList == 'shared', onEditItem: e => this.editHistoryItem(e.detail), selected: this.selectedHistoryItems.findIndex(id => id == item.id) > -1, onItemSelected: (e) => this.selectedItemChanged(e.detail), alternateRow: (index + 2) % 2 ? 'even' : 'odd', onFilterChanged: e => this.clickFilterByTag(e.detail) }));
                  if (this.showDateHeaders) {
                    const createdDate = item.created ? new Date(item.created) : null;
                    const prevCreatedDate = index > 0 && items[index - 1].created ? new Date(items[index - 1].created) : null;
                    // should show date header if the date changed or if this is the first item
                    if (index == 0 || !isSameDay(createdDate, prevCreatedDate)) {
                      return (h("div", null,
                        createdDate && (h("h5", { class: `${index > 0 && 'mt-4'} mb-3` },
                          isToday(createdDate) && 'Today, ',
                          isYesterday(createdDate) && 'Yesterday, ',
                          format(createdDate, 'EEEE, MMMM d, yyyy'))),
                        renderedItem));
                    }
                  }
                  return renderedItem;
                })))))),
      ((_c = this.editableHistoryItem) === null || _c === void 0 ? void 0 : _c.current) && this.renderEditFavoriteDialog(),
      h("gd-user-dashboard-export-dialog", { show: this.showExportDialog, historyItemIds: this.selectedHistoryItems, onClosed: () => (this.showExportDialog = false), onShare: () => (this.showShareDialog = true), canShareAsUrl: this.canShareAsUrl }),
      h("gd-user-dashboard-share-dialog", { show: this.showShareDialog, historyItemIds: this.selectedHistoryItems, onClosed: () => (this.showShareDialog = false) }),
      h("gd-user-dashboard-import-dialog", { show: this.showImportDialog, onClosed: () => (this.showImportDialog = false) }),
      h("gd-user-dashboard-import-datalist-dialog", { show: this.showDatalistImportDialog, onClosed: () => this.cancelDatalistImport.emit(), datalist: this.activeDatalist }),
      h("gd-user-dashboard-bulk-tag-dialog", { show: this.showBulkTagDialog, historyItemIds: this.selectedHistoryItems, onClosed: () => (this.showBulkTagDialog = false), onAddTags: (e) => this.bulkAddTags(e.detail) })));
  }
  renderEditFavoriteDialog() {
    var _a, _b, _c;
    return (h("bs-modal", { static: true, show: true, onClose: () => this.stopEditingHistoryItem() },
      h("bs-modal-header", { "modal-title": '<bs-icon size="20" class="mr-2" icon="fab fa-edit"></bs-icon> Edit Favorite' }),
      h("bs-modal-body", null,
        h("bs-form-row", null,
          h("bs-form-group", { stack: false },
            h("bs-form-label", null, "Label"),
            h("bs-form-control", { "control-id": "label", as: "input", name: "label", type: "text", value: (_a = this.editableHistoryItem) === null || _a === void 0 ? void 0 : _a.current.label, onBsInput: (e) => (this.editableHistoryItem.changes.label = e.detail.target.value) }))),
        h("bs-form-row", null,
          h("bs-form-group", { stack: false },
            h("bs-form-label", null, "Tags"),
            ((_b = this.editableHistoryItem) === null || _b === void 0 ? void 0 : _b.current.tags) && (h("gd-tag-input", { defaultValue: (_c = this.editableHistoryItem) === null || _c === void 0 ? void 0 : _c.current.tags, variant: "pills", placeholder: "Add tag...", onTagsChange: (event) => {
                var _a;
                if (!((_a = this.editableHistoryItem) === null || _a === void 0 ? void 0 : _a.changes))
                  return;
                this.editableHistoryItem.changes.tags = event.detail;
              } }))))),
      h("bs-modal-footer", null,
        h("bs-button", { variant: "secondary", onClick: () => this.stopEditingHistoryItem() }, "Cancel"),
        h("bs-button", { variant: "primary", onClick: () => this.saveHistoryItemChanges(this.editableHistoryItem.changes) }, "Save changes"))));
  }
  static get is() { return "gd-user-dashboard"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["gd-user-dashboard.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["gd-user-dashboard.css"]
  }; }
  static get properties() { return {
    "items": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "Array<HistoryItem>",
        "resolved": "HistoryItem[]",
        "references": {
          "Array": {
            "location": "global"
          },
          "HistoryItem": {
            "location": "import",
            "path": "../gd-user-dashboard-list-item/user-dashboard-list-item"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "dashboard list items"
      },
      "defaultValue": "null"
    },
    "tags": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "Array<HistoryItemTag>",
        "resolved": "HistoryItemTag[]",
        "references": {
          "Array": {
            "location": "global"
          },
          "HistoryItemTag": {
            "location": "local"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "a list of tags to show in the filter by dropdown"
      },
      "defaultValue": "[]"
    },
    "showDateHeaders": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "whether to split the history items by showing date headers"
      },
      "attribute": "show-date-headers",
      "reflect": false,
      "defaultValue": "true"
    },
    "activeDatalist": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "Datalist",
        "resolved": "{ description: string; url: string; historyItems: HistoryItem[]; }",
        "references": {
          "Datalist": {
            "location": "local"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "an active datalist"
      }
    },
    "canShareAsUrl": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "if the share as url functionality should be available or not"
      },
      "attribute": "can-share-as-url",
      "reflect": false,
      "defaultValue": "false"
    }
  }; }
  static get states() { return {
    "historyItems": {},
    "activeList": {},
    "selectedTag": {},
    "editableHistoryItem": {},
    "selectedHistoryItems": {},
    "showExportDialog": {},
    "showShareDialog": {},
    "showImportDialog": {},
    "showBulkTagDialog": {},
    "showDatalistImportDialog": {}
  }; }
  static get events() { return [{
      "method": "activeListChanged",
      "name": "activeListChanged",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "an event that is fired when the list changes, would be a good time to refresh the list"
      },
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      }
    }, {
      "method": "filterChanged",
      "name": "filterChanged",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "an event that is fired when the user selects a tag to filter by"
      },
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      }
    }, {
      "method": "saveHistoryItem",
      "name": "saveHistoryItem",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "an event that is triggered to inform the application that a history item needs to be updated"
      },
      "complexType": {
        "original": "HistoryItem",
        "resolved": "HistoryItem",
        "references": {
          "HistoryItem": {
            "location": "import",
            "path": "../gd-user-dashboard-list-item/user-dashboard-list-item"
          }
        }
      }
    }, {
      "method": "deleteHistoryItems",
      "name": "deleteHistoryItems",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "an event that is triggered to inform the application that one or more history items need to be deleted"
      },
      "complexType": {
        "original": "string[]",
        "resolved": "string[]",
        "references": {}
      }
    }, {
      "method": "cancelDatalistImport",
      "name": "cancelDatalistImport",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "an event triggered when the user clicks cancel on the datalist import dialog"
      },
      "complexType": {
        "original": "void",
        "resolved": "void",
        "references": {}
      }
    }, {
      "method": "updateHistoryItems",
      "name": "updateHistoryItems",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "used by the application to save changes that have been made to multiple history items"
      },
      "complexType": {
        "original": "HistoryItem[]",
        "resolved": "HistoryItem[]",
        "references": {
          "HistoryItem": {
            "location": "import",
            "path": "../gd-user-dashboard-list-item/user-dashboard-list-item"
          }
        }
      }
    }]; }
  static get methods() { return {
    "setActiveList": {
      "complexType": {
        "signature": "(listType: DashboardListType) => Promise<void>",
        "parameters": [{
            "tags": [{
                "text": "listType",
                "name": "param"
              }],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          },
          "DashboardListType": {
            "location": "local"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "an exposed method to change the visible list",
        "tags": [{
            "name": "param",
            "text": "listType"
          }]
      }
    }
  }; }
  static get watchers() { return [{
      "propName": "activeList",
      "methodName": "notifyOfListChange"
    }, {
      "propName": "activeDatalist",
      "methodName": "handleActiveDatalistChanged"
    }, {
      "propName": "items",
      "methodName": "handleItemsChanged"
    }]; }
}
