import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload';
import {MessageBoxComponent} from '../message-box/message-box.component';
import {SessionService} from '../service/session.service';
import {AppConfig} from '../app.config';
import {PeopleService} from '../service/people.service';
import {NotificationService, Type} from '@progress/kendo-angular-notification';
import {UserExModel, UserRoles} from '../models/user-ex.model';
import {ActivatedRoute, Router} from '@angular/router';
import {DialItem, DialItemClickEvent} from '@progress/kendo-angular-buttons';

@Component({
  selector: 'app-contact-edit',
  templateUrl: './contact-edit.component.html',
  styleUrls: ['./contact-edit.component.scss']
})
export class ContactEditComponent implements OnInit {
  @Input() public People = new UserExModel({Id:'', Display: 'Add New People'});
  public avatarUrl = 'url(https://via.placeholder.com/128)' ;
  public myRestrictions: FileRestrictions = {
    allowedExtensions: ['.jpg', '.png', '.jpeg'],
    maxFileSize: 2194304
  };

  public featureUser = false;
  public featureBroker= false;
  public roleAdmin = false;
  public roleManager = false;
  public roleAccountant= false;

  public dialOpen = false;
  public actionItems: Array<DialItem> = [
    { icon: "save", label: "Save" },
    { icon: "table", label: "List all people" },
    { icon: "delete", label:  "Delete" },
  ];
  private timer: any;

  @ViewChild('messagebox', {static: true}) msgBox: MessageBoxComponent;
  @ViewChild('fileSelect', {static: true}) fs: FileSelectComponent;
  constructor(public ss: SessionService, private config: AppConfig,
              private actRoute: ActivatedRoute, private router: Router,
              private ps: PeopleService, private  notificationService: NotificationService) { }

  ngOnInit(): void {
    // stand along editing
    let path = this.actRoute.snapshot.routeConfig.path
    if (path === 'contact' && this.ss.canEditOtherUser() ){
      this.createNew();
    }else if ( path === 'contact/:id' ){
      this.editById();
    }else{ // embedded editing
      this.embedEditing();
    }
    this.avatarUrl = 'url(' + this.config.getUrl('avatar/' + this.People.Id) + ')';
  }

  onDialogClose(status: string): void {
    console.log(status);
  }

  private embedEditing(): void {
    if ( this.People.Id === '') {
      console.log(this.ss);
      if ( this.ss.canEditOtherUser() ){
        this.People.Display = "Add New People"
      }else{
        this.router.navigate(['/profile'])
      }
    }else{// People Id is not null
      if ( this.People.Id === this.ss.loggedIn.UserEx.Id ) { //edit oneself
        this.People = this.ss.loggedIn.UserEx;
      }else {
        if ( this.ss.canEditOtherUser()){
          this.loadUserEx(this.People.Id);
        }
      }
    }
  }

  private editById (): void {
    const id = this.actRoute.snapshot.params.id;
    if ( id === '' ){
      this.createNew();
    }else{
      this.loadUserEx(id);
    }
  }

  private createNew() {
    this.People = new UserExModel();
    this.People.Display = "Add New People"
  }

  private loadUserEx(id: string) {
    if (!id  || id === '' ) return ;
    this.ps.getUserEx(id).subscribe( resp => {
      this.People = new UserExModel(resp);
      this.avatarUrl = 'url(' + this.config.getUrl('avatar/' + this.People.Id) + ')';
      this.People.defaultContact = this.People.Contacts[0];
      switch ( this.People.Role.toLowerCase() ){
        case "admin":
          this.roleAdmin = true;
          this.roleManager = false;
          this.roleAccountant = false;
          this.roleAccountant = false;
          break
        case "manager":
          this.roleAdmin = false;
          this.roleManager = true;
          this.roleAccountant = false;
          break
        case "accountant":
          this.roleAdmin = false;
          this.roleManager = true;
          this.roleAccountant = false;
          break;
        case "user":
          this.featureUser = true;
          this.featureBroker = false;
          break;
        case "broker":
          this.featureUser = true;
          this.featureBroker = true;
          break;
        case "people":
          this.featureUser = false;
          this.featureBroker = false;
          break;
      }
      console.log(this, resp);
    });
  }

  public onSelectAvatar(ev: SelectEvent): void {
    if (ev.files) {
      ev.files.every((file: FileInfo) => {
        if (file.rawFile && !file.validationErrors) {
          const reader  = new FileReader();

          reader.onloadend = () => {
            const str = reader.result as string;
            this.People.Avatar = str;
            if (this.People.Id !== ''){
              this.ps.updateAvatar(str, this.People.Id).subscribe(resp => {
                this.avatarUrl = 'url(' + str + ' )';
              }, err => {
                this.msgBox.Show('Failed to Update Avatar: ' + err.toString());
              });
            }else{ // we are new user, we update ui only
              this.avatarUrl = 'url(' + str + ' )';
            }
            // this.fs.clearFiles();
          };
          reader.readAsDataURL(file.rawFile);
        }else{
          this.msgBox.Show('Only jpg, and png are supported (max 2MB)');
          setTimeout(() => { this.fs.clearFiles(); }, 10);
        }
        return false; // we only take first file
      });
    }
  }

  public startSelectAvatar(): void {
    const element: NodeListOf<HTMLElement> = document.getElementsByName('selectAvatar');
    element.forEach( v => {
      if ( v.tagName.toLowerCase() === 'input') {
        v.click();
      }
    });
  }

  public onEnableDisable() : void{
    if ( this.People.Id === '' ) { return; }
    this.ps.enableUser(this.People.Enabled, this.People.Id).subscribe(resp => {
      if ( resp ) {
        this.notifyEnabled(this.People.Display + " Enabled", { style: 'success', icon: true });
      }else{
        this.notifyEnabled(this.People.Display + " Disabled", { style: 'warning', icon: true });
      }
    });
  }

  public notifyEnabled( msg: string, lookAndFeel?: Type): void {
    if (lookAndFeel === undefined ){
      lookAndFeel = { style: 'success', icon: true };
    }
    this.notificationService.show({
      content: msg,
      cssClass: 'button-notification',
      animation: { type: 'slide', duration: 400 },
      position: { horizontal: 'right', vertical: 'top' },
      type: lookAndFeel,
      closable: false,
      hideAfter: 5000,
    });
  }

  public onEnableFeatureUser(): void{
    if ( this.People.Login === '' && this.People.Enabled) {
      this.People.Login = Date.now() + "@sfmarkets.com.au";
      if ( this.People.Role === UserRoles.People ) {
        this.People.Role = UserRoles.User; // upgrade to user
      }
    }else{
      if ( this.People.Role === UserRoles.User) { // downgrade to people
        this.People.Role = UserRoles.People;
      }
    }
  }

  public onEnableFeatureBroker(): void {
    if (this.featureBroker){
      this.People.Broker.Id = this.People.Id;
      this.People.Broker.First = this.People.First;
      this.People.Broker.Last = this.People.Last;
      this.People.Broker.Middle = this.People.Middle;
      this.People.Broker.Title = this.People.Title;
      this.People.Broker.Nick = this.People.Nick;
      this.People.Broker.Display = this.People.Display;
      if ( this.People.Role === UserRoles.User ) {
        this.People.Role = UserRoles.Broker; // upgrade to Broker
      }
    }else{
      this.People.Broker.Id = "";
      if ( this.People.Role === UserRoles.Broker ){
        this.People.Role = UserRoles.User;  // downgrade to User
      }
    }
  }
  public onEnableRoleAdmin(): void {
    if (this.roleAdmin) {this.roleAccountant = false; this.roleManager = false;}
    this.People.Role = UserRoles.Admin;
  }
  public onEnableRoleManager(): void {
    if (this.roleManager) {this.roleAdmin = false; this.roleAccountant = false;}
    this.People.Role = UserRoles.Manager;
  }
  public onEnableRoleAccountant(): void{
    if (this.roleAccountant) {this.roleAdmin = false; this.roleManager = false;}
    this.People.Role = UserRoles.Accountant;
  }
  public onFloatButtonAction(dice: DialItemClickEvent): void{
    switch( dice.index.toString() ) {
      case '0':
        this.doSave();
        break;
      case '1':
        this.router.navigate(['/list-all-people']);
        break;
      case '2':
        this.doDelete();
        break;
    }
    // this.notifyEnabled(dice.item.label);
  }
  public onDialOpen(): void {
    this.dialOpen = true;
    this.actionItems[2].disabled = true;
    if (this.People.Id === '') { return ; }
    let count = 3;
    let self = this;
    this.timer = setInterval(() => {
      count --;
      this.actionItems[2].label = 'wait .. ' + count;
      if ( count < 0 ) {
        this.actionItems[2].label = 'delete: ' + this.People.Display;
        this.actionItems[2].disabled = false;
        clearInterval(self.timer);
      }
    }, 1000)
  }

  public onDialClose(): void {
    this.dialOpen = false;
    clearInterval(this.timer);
  }

  private doDelete(): void {
    if (this.People.Id === '') {
      this.createNew();
      return
    }else{
      this.ps.deletePeople(this.People.Id).subscribe(
        resp => {
          if ( resp === this.People.Id ) { // successfully deleted
            this.msgBox.Show('User and all of his/her related loans payment has been deleted !!');
            this.createNew();
            this.router.navigate(['/list-all-people']).then(
              v =>  this.notifyEnabled( "User " + this.People.Display + " deleted")
            );
          }
        }, err => {
          this.msgBox.Show('"Error Delete People');
        }
      );
    }
  }

  private doSave(): void {
    this.ps.saveUserEx(this.People).subscribe(
      resp => { this.People.Id = resp.Id; },
      err => { this.msgBox.Show('Err saving user, please try again later'); },
      () => {}
    );
  }
}
