import { CustomLogger } from './../../modules/custom-logger';
import { Router } from 'aurelia-router';
import { UITreeNode } from './../data/ui-tree-model';
import { BindingEngine, children, Disposable, observable } from 'aurelia-framework';
import { HttpClient } from 'aurelia-fetch-client';
import { autoinject, customElement } from 'aurelia-framework';
import { Config } from '../../config';
import { ViewModelBase } from '../../vm/view-model-base';

@customElement('metadata-detail')
@autoinject
export class MetadataDetail extends ViewModelBase {
  public ribbonHeaderText = "";
  public ressourceName = "";
  public Format: any = Format;
  private familiesTree: any[] = [];
  private selectedTreeValues: any[] = [];

  private entitySelected: EntityMetadata;

  constructor(public router: Router, public logger: CustomLogger, public config: Config, private httpClient: HttpClient, private bindingEngine: BindingEngine) {
    super(router, logger);
  }

  async bind() {
    await this.getMetadata();
  }


  public async getMetadata() {
    this.familiesTree.splice(0);
    let result = await this.httpClient.fetch(this.config.globalConfig.remoteServiceName + "/api/metadata");
    if (result.ok) {
      let metadata = await result.json();
      console.log("Metadata : ", metadata);
      metadata.forEach(element => {
        let tree: UITreeNode = new UITreeNode({
          id: element.ClrEntityType,
          label: element.ClrEntityType,
          model: element,
          leaf: false,
          isSelectable: true,
          children: []
        });
        element.Properties.forEach(property => {
          tree.children.push(new UITreeNode({
            id: property.Id.toString(),
            label: property.ClrPropertyType,
            leaf: true,
            isSelectable: false,
            children: []
          }));
        });
        this.disposables.push(
          this.bindingEngine.propertyObserver(tree, "selected").subscribe((newValue, oldValue) => {
            if (newValue != oldValue) {
              this.entitySelected = this.familiesTree.find(x => x.selected).model;
            }
          })
        );
        this.familiesTree.push(tree);
      });
      if (this.entitySelected) {
        this.entitySelected = this.familiesTree.find(x => x.model.ClrEntityType == this.entitySelected.ClrEntityType).model;
      }
    }
  }

  private async saveEntityMetadata(entityMetadata: EntityMetadata) {
    let response = await this.httpClient.post(this.config.globalConfig.remoteServiceName + "/api/metadata/entity", JSON.stringify(entityMetadata));
  }

  private async savePropertyMetadata(propertyMetadata: EntityPropertyMetadata) {
    let response = await this.httpClient.post(this.config.globalConfig.remoteServiceName + "/api/metadata/property", JSON.stringify(propertyMetadata));
  }

  private async save(entityMetadata: EntityMetadata) {
    await this.saveEntityMetadata(entityMetadata);
    await Promise.all(
      entityMetadata.Properties.map(async (property) => {
        await this.savePropertyMetadata(property);
      })
    );
    await this.getMetadata();
  }
}


interface EntityMetadata {
  Id: number;
  CreatedById: number;
  CreatedByFullName: string;
  CreatedTime: Date;
  UpdatedById: number;
  UpdatedByFullName: string;
  UpdatedTime: Date;
  ClrEntityType: string;
  IsAuditable: boolean;
  IsChatable: boolean;
  Icon: string;
  Properties: Array<EntityPropertyMetadata>
}
interface EntityPropertyMetadata {
  Id: number;
  CreatedById: number;
  CreatedByFullName: string;
  CreatedTime: Date;
  UpdatedById: number;
  UpdatedByFullName: string;
  UpdatedTime: Date;
  ClrPropertyType: string;
  IsAuditable: boolean;
  EntityMetadataId: number;
  Type: string;
  Format: string;
  FormatedString: string;
}
class Format {
  public static None = "None";
  public static Currency = "Currency";
  public static Number = "Number";
  public static Date = "Date";
  public static DateTime = "DateTime";
  public static Time = "Time";
}
