/*
 * Copyright (C) 2022 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * 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 General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {Component, ContentChild, Input, TemplateRef} from '@angular/core';
import {DataListContext} from './data-list.component';
import {SCThings, SCThingWithoutReferences, SCUuid} from '@openstapps/core';
import {Tree, treeGroupBy} from '@openstapps/collection-utils';

@Component({
  selector: 'tree-list',
  templateUrl: 'tree-list.html',
  styleUrls: ['tree-list.scss'],
})
export class TreeListComponent {
  _items?: Promise<SCThings[] | undefined>;

  _groupingKey?: string;

  _groups?: Promise<Tree<SCThings> | undefined>;

  _groupItems?: Record<SCUuid, SCThingWithoutReferences>;

  @Input() set groupingKey(value: keyof SCThings | string | undefined) {
    this._groupingKey = value;
    this.groupItems();
  }

  @Input() set items(items: Promise<SCThings[] | undefined> | undefined) {
    this._items = items;
    this.groupItems();
  }

  @Input() singleType = false;

  @ContentChild(TemplateRef) listItemTemplateRef: TemplateRef<DataListContext<SCThings>>;

  groupItems() {
    if (!this._items || !this._groupingKey) return;

    this._groups = this._items.then(items => {
      if (!items || !this._groupingKey) return;

      this._groupItems = {};
      for (const item of items) {
        const path = (item as unknown as Record<string, SCThingWithoutReferences[]>)[this._groupingKey];

        for (const pathFragment of path) {
          this._groupItems[pathFragment.uid] = pathFragment;
        }
      }

      const tree = treeGroupBy(items, item =>
        (item as unknown as Record<string, SCThingWithoutReferences[]>)[
          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
          this._groupingKey!
        ].map(thing => thing.uid),
      );
      return tree;
    });
  }
}
