import { Component, ViewChild } from '@angular/core';
import { faAdd, faFilter } from '@fortawesome/free-solid-svg-icons';
import { combineLatest } from 'rxjs';
import { Action } from '../../models/action';
import { Filter } from '../../models/filter';
import { Query } from '../../models/query';
import { TreeNode } from '../../models/tree-node';
import { MetaService } from '../../services/meta.service';
import { QueryService } from '../../services/query.service';
import { FilterConfigComponent } from '../filter-config/filter-config.component';
import { TreeComponent } from '../tree/tree.component';
import { WindowComponent } from '../window/window.component';

@Component({
  selector: 'fbi-metadata',
  standalone: true,
  imports: [FilterConfigComponent, TreeComponent, WindowComponent],
  templateUrl: './metadata.component.html',
  styleUrl: './metadata.component.scss',
})
export class MetadataComponent {
  node: TreeNode = new TreeNode({});
  @ViewChild(WindowComponent) window!: WindowComponent;

  windowComponent = WindowComponent;
  windowConfig = {
    title: 'test',
  };
  filter: Filter = new Filter({});

  constructor(metaService: MetaService, private queryService: QueryService) {
    combineLatest({
      meta: metaService.Data$,
      query: queryService.Query$,
    }).subscribe((d: { meta: Partial<TreeNode>[]; query: Query }) => {
      const inuse = d.query.fields;
      const expanded = this.getExpanded(this.node);

      const recurse = (node: Partial<TreeNode>) => {
        node.hidden = inuse.includes(node.data);
        node.expanded = expanded.includes(node.data);

        const children = node.children ?? [];
        children.forEach((child: Partial<TreeNode>) => recurse(child));
        if (children.length === 0) {
          const actions = [
            { label: 'Filter', icon: faFilter, data: ACTIONS.FILTER },
            { label: 'Add', icon: faAdd, data: ACTIONS.ADD },
          ];
          node.actions = actions as Action[];
        }
      };

      (d.meta ?? []).forEach((node: Partial<TreeNode>) => recurse(node));

      this.node = new TreeNode({
        hidden: true,
        expanded: true,
        children: d.meta as TreeNode[],
      });
    });
  }

  onActionClick(event: { action: Action; node: TreeNode }): void {
    switch (event.action.data) {
      case ACTIONS.ADD:
        this.queryService.add(event.node.data);
        break;
      case ACTIONS.FILTER:
        this.filter = new Filter({ field: event.node.data });
        this.window.show();
        break;
    }
  }

  private getExpanded(node: TreeNode): string[] {
    const result: string[] = [];

    if (node.expanded) {
      result.push(node.data);
    }
    (node.children ?? []).forEach((child: TreeNode) =>
      result.push(...this.getExpanded(child))
    );

    return result;
  }
}

enum ACTIONS {
  ADD = 'add',
  FILTER = 'filter',
}
