import { Component, Optional, AfterViewInit, Output, EventEmitter, Input } from '@angular/core';
import { MdDialogRef } from '@angular/material';
import { TerritoryResponsibility } from '../../model/territory-responsibility';
import { MessageService } from '../../services/message.service';
import { ResponsibilityService } from '../../services/responsibility.service';
import { BannerMessage } from '../../common/banner-message';
import { BannerMessageStatusEn, ErrorType } from '../../common/enums';
import { ShiftChangeProtocolComponent } from '../shift-change-protocol/shift-change-protocol.component';
import { SessionContext } from '../../common/session-context';

@Component({
  selector: 'app-responsibility',
  templateUrl: './responsibility.component.html',
  styleUrls: ['./responsibility.component.css']
})
export class ResponsibilityComponent implements AfterViewInit {

  @Input()
  responsiblitySelection: TerritoryResponsibility[];
  @Input()
  withButtons = true;
  @Input()
  withNames = false;

  bannerMessageStatus = BannerMessageStatusEn;

  constructor(
    @Optional() public dialogRef: MdDialogRef<ShiftChangeProtocolComponent>,
    private messageService: MessageService,
    private sessionContext: SessionContext,
    private responsibilityService: ResponsibilityService
  ) { }


  ngAfterViewInit() {
    this.responsibilitiesSelectionChanged();
  }

  confirm(): void {
    this.responsibilityService.confirmResponsibilities(this.responsiblitySelection).subscribe((resps: TerritoryResponsibility[]) => {
      if (resps['ret'] && resps['ret'] === 'OK') {
        this.responsiblitySelection = [];
        this.messageService.deactivateMessage();
        this.dialogRef.close();
      } else {
        const message = 'Ihre Verantwortlichkeiten haben sich geändert. ' +
          'Bitte prüfen Sie Ihre Eingaben und versuchen Sie es erneut.';
        this.messageService.emitWarning(message);
        this.responsiblitySelection = resps;
      }
    },
      error => {
        this.dialogRef.close();
        this.messageService.emitError('Verantwortlichkeiten', ErrorType.update);
      }
    );
    function setResp(respCs: TerritoryResponsibility[]): void {

    }
  }

  responsibilitiesSelectionChanged() {
    const filterList: number[] = [];

    if (!this.responsiblitySelection) { return; }

    for (const responsibilityContainer of this.responsiblitySelection) {
      for (const responsibility of responsibilityContainer.responsibilityList) {
        if (responsibility.isActive) {
          filterList.push(responsibility.id);
        }
      }
    }
    this.messageService.matrixFilterChanged$.emit(filterList);
  }

  getResponsiblity(responsibilityContainer: TerritoryResponsibility, branchName: string) {
    return responsibilityContainer.
      responsibilityList ? responsibilityContainer.responsibilityList.
        find(responsibility => responsibility.branchName === branchName) : [];
  }

  selectAllResponsibilities() {
    for (const responsibilityContainer of this.responsiblitySelection) {
      for (const responsibility of responsibilityContainer.responsibilityList) {
        responsibility.isActive = true;
      }
    }
    this.responsibilitiesSelectionChanged();
  }

  deselectAllResponsibilities() {
    for (const responsibilityContainer of this.responsiblitySelection) {
      for (const responsibility of responsibilityContainer.responsibilityList) {
        responsibility.isActive = false;
      }
    }
    this.responsibilitiesSelectionChanged();
  }

  mapUserName( shortUsr: string ) {
    const userMap = this.sessionContext.getUserMap();
    return userMap ? this.sessionContext.getUserMap().findAndRenderUser(shortUsr) : shortUsr;
  }    

}
