import {Component, Input, ViewChild} from '@angular/core';
import {AlertModal} from '../../../utils/modal/alert';
import {ClaimEntity, ClaimsErrorMessage, Message, ShowOptions} from '../../claim-utils/claimHelper.class';
import {EnvProperties} from "../../../utils/properties/env-properties";
import {Dates} from "../../../utils/string-utils.class";
import {HelperFunctions} from "../../../utils/HelperFunctions.class";

@Component({
  selector: 'metadata-preview',
  templateUrl: 'metadataPreview.component.html'

})
export class MetadataPreviewComponent {

/*  showSources = true;
  showLinksTo = true;*/
  // showErrors = true;
  // showWarnings = true;
  @Input() results: ClaimEntity[];
  @Input() sources: ClaimEntity[];
  @Input() title: string = "Research Results";
  @Input() bulkMode: boolean = false;
  @Input() inlineEntity: ClaimEntity = null;
  @Input() showOptions:ShowOptions;
  @Input() public properties: EnvProperties;
  @Input() pageContents;
  @Input() defaultColors:boolean=true;
  @ViewChild(AlertModal) alertApplyAll;
  @Input() localStoragePrefix: string = "";
  @Input() communityId:string= null;
  errors:ClaimsErrorMessage[] = [];
  warnings:Message[] = [];
  public commonAccessRights = "OPEN"; // for access rights- changes when user apply a change to every entity
  public commonEmbargoEndDate; // for access rights: embargoEndDate - changes when user apply a change to every entity
  public commonType; // for research entity type - changes when user apply a change to every entity
  public applyToResults: boolean; // true apply to results, false apply to sources
  public typeChanged: boolean = true; //
  accessTypes = ["OPEN", "CLOSED", "EMBARGO", "RESTRICTED"];
  embargoEndDates = [];

  ngOnInit() {
    this.setEmbargoEndDates();
/*    if (this.inlineEntity) {
      this.showSources = true;
      this.showLinksTo = true;
    }*/
    this.runValidation(true);
  }
  setEmbargoEndDates(){
    for(let entity of this.sources){
      if(entity.result){
        this.embargoEndDates[entity.id+"_source"] = MetadataPreviewComponent.getDate(entity.result.embargoEndDate);
        // entity.result.accessRights = "EMBARGO";
      }
    }
    for(let entity of this.results){
      if(entity.result){
        this.embargoEndDates[entity.id+"_result"] = MetadataPreviewComponent.getDate(entity.result.embargoEndDate);
      }
    }
  }
  private static getDate(date:string){
    let myDate = new Date();
    if(date){
       myDate = new Date(date);
    }
    return myDate;
  }

 /* removePublication(item: ClaimEntity) {
    var index: number = this.results.indexOf(item);
    if (index > -1) {
      this.results.splice(index, 1);
      if (this.results != null) {
        localStorage.setItem(this.localStoragePrefix, JSON.stringify(this.results));
      }
    }

  }*/

  onDateChanged(event: any, item: ClaimEntity, applyToResults) {
    item.result.embargoEndDate = Dates.getDateToString(event.value);
    this.embargoEndDates [item.id+"_"+(applyToResults?'result':'source')] = event.value;
    if ((applyToResults && this.results.length > 1) || (!applyToResults && this.sources.length > 1)) {
      this.commonAccessRights = "EMBARGO";
      this.commonEmbargoEndDate = item.result.embargoEndDate;
      this.applyToResults = applyToResults;
      this.confirmOpen(false);
    }
    this.updateLocalStorage();
    this.runValidation(true);

  }

  onTypeChanged(event: any, item: ClaimEntity, applyToResults) {
    item.type = (event);
    if ((applyToResults && this.results.length > 1) || (!applyToResults && this.sources.length > 1)) {
      this.commonType = item.type;
      this.applyToResults = applyToResults;
      this.confirmOpen(true );
    }
    this.updateLocalStorage();
  }

  //  resultsChanged($event) {
  //    this.results=$event.value;
  //    this.resultsChange.emit({
  //      value: this.results
  //    });
  //  }
  /* The following methods:
     *typeChanged
     *confirmOpen
     *confirmClose
   implement the functionality: change accessRights of a publication - apply to all if asked */
  accessRightsTypeChanged(type: any, item: any, applyToResults) {
    item.accessRights = type;
    if ((applyToResults && this.results.length > 1) || (!applyToResults && this.sources.length > 1)) {
      this.commonAccessRights = type;
      this.applyToResults = applyToResults;
      if (this.commonAccessRights != "EMBARGO") {
        this.commonEmbargoEndDate = item.embargoEndDate;
        this.confirmOpen(false );
      }
    }
    this.runValidation(true);

    this.updateLocalStorage();

  }

  confirmOpen(type: boolean) {
    this.typeChanged = type;
    this.alertApplyAll.cancelButton = true;
    this.alertApplyAll.okButton = true;
    this.alertApplyAll.alertTitle = "Change metadata";
    this.alertApplyAll.message = "Do you wish to apply the change to every entity?";
    this.alertApplyAll.okButtonText = "Yes";
    this.alertApplyAll.cancelButtonText = "No";
    this.alertApplyAll.open();
  }

  confirmClose() {
    if (this.typeChanged) {
      if (this.applyToResults) {
        for (let i = 0; i < this.results.length; i++) {
          if (this.results[i].result.source != 'openaire' && this.results[i].type != 'project' && this.results[i].type != 'community') {
            this.results[i].type = this.commonType;
          }
        }
      } else {
        for (let i = 0; i < this.sources.length; i++) {
          if (this.sources[i].result.source != 'openaire' && this.sources[i].type != 'project' && this.sources[i].type != 'community') {
            this.sources[i].type = this.commonType;
          }
        }
      }

    } else {
      if (this.applyToResults) {
        for (let i = 0; i < this.results.length; i++) {
          if (this.results[i].result.source != 'openaire' && this.results[i].type != 'project' && this.results[i].type != 'community') {
            this.results[i].result.accessRights = this.commonAccessRights;
            if (this.commonAccessRights == "EMBARGO") {
              this.results[i].result.embargoEndDate = this.commonEmbargoEndDate;
            }
          }
        }
      } else {
        for (let i = 0; i < this.sources.length; i++) {
          if (this.sources[i].result.source != 'openaire' && this.sources[i].type != 'project' && this.sources[i].type != 'community') {
            this.sources[i].result.accessRights = this.commonAccessRights;
            if (this.commonAccessRights == "EMBARGO") {
              this.sources[i].result.embargoEndDate = this.commonEmbargoEndDate;
            }
          }
        }
      }
      this.setEmbargoEndDates();
    }
    this.updateLocalStorage();
    this.runValidation(true)
  }

  remove(item: any, applyToResults: boolean) {
    if (applyToResults) {
      let index: number = this.results.indexOf(item);
      item.warningMessages.splice(0, item.warningMessages.length);
      if (index > -1) {
        this.results.splice(index, 1);
        localStorage.setItem(this.localStoragePrefix + 'results', JSON.stringify(this.results));
      }
    } else {
      let index: number = this.sources.indexOf(item);
      item.warningMessages.splice(0, item.warningMessages.length);
      if (index > -1) {
        this.sources.splice(index, 1);
        localStorage.setItem(this.localStoragePrefix + 'sources', JSON.stringify(this.sources));

      }
    }
    this.updateLocalStorage();
    this.runValidation(true);
  }

  addStringToNumber(str: string, num: number) {
    return (+str) + num;
  }

  runValidation(cleanErrors:boolean) {
    this.warnings = [];
    if(cleanErrors){
      this.errors = [];
    }
    if (this.inlineEntity) {
      this.inlineEntity.warningMessages = [];
      if(cleanErrors){
        this.inlineEntity.errorMessages = [];
      }

    }
    this.validateEmbargoDate(this.sources, cleanErrors);
    this.validateEmbargoDate(this.results, cleanErrors);
    this.validateProjectDuration();

  }

  validateProjectDuration() {
    for (let item of this.results) {
      if (item.type == 'project' && item.project) {
        for (let result of this.sources) {
          if (result.result && result.result.date) {
            if ((item.project.startDate && result.result.date < item.project.startDate) || (item.project.endDate && +result.result.date > (5 + +item.project.endDate))) {
              const message: Message = {
                type: 'projectDuration',
                resultId: result.id,
                resultTitle: result.title,
                projectId: item.id,
                projectInfo: {title: item.title, startDate: item.project.startDate, endDate: item.project.endDate}
              };
              result.warningMessages.push(message);
              this.warnings.push(message);
            }
          }
        }
        if (this.inlineEntity && this.inlineEntity.result) {
          if (this.inlineEntity.result.date) {
            if ((item.project.startDate && this.inlineEntity.result.date < item.project.startDate) || (item.project.endDate && +this.inlineEntity.result.date > (5 + +item.project.endDate))) {
              const message: Message = {
                type: 'projectDuration',
                resultId: this.inlineEntity.id,
                resultTitle: this.inlineEntity.title,
                projectId: item.id,
                projectInfo: {title: item.title, startDate: item.project.startDate, endDate: item.project.endDate}
              };
              this.inlineEntity.warningMessages.push(message);
              this.warnings.push(message);
            }
          }
        }
      }
    }
      if (this.inlineEntity && this.inlineEntity.project) {
        for (let result of this.results) {
          if (result.result && result.result.date) {
            if ((this.inlineEntity.project.startDate && result.result.date < this.inlineEntity.project.startDate) || (this.inlineEntity.project.endDate && +result.result.date > (5 + +this.inlineEntity.project.endDate))) {
              const message: Message = {
                type: 'projectDuration',
                resultId: result.id,
                resultTitle: result.title,
                projectId: this.inlineEntity.id,
                projectInfo: {title: this.inlineEntity.title, startDate: this.inlineEntity.project.startDate, endDate: this.inlineEntity.project.endDate}
              };
              result.warningMessages.push(message);
              this.warnings.push(message);
            }
          }
        }
      }


  }

  validateEmbargoDate(sources: ClaimEntity [],cleanErrors:boolean) {
    for (let entity of sources) {
      entity.warningMessages = [];
      if(cleanErrors){
        entity.errorMessages = [];
      }

      if(entity.result) {
        // console.log(entity.result.accessRights + " " + entity.result.date + " " + entity.result.embargoEndDate);
        if (entity.result.accessRights && entity.result.accessRights == 'EMBARGO' && entity.result.date && (entity.result.embargoEndDate) && entity.result.date > entity.result.embargoEndDate.substr(0, 4)) {
          let message: Message = new Message();
          message.type = "embargoEndDate";
          message.resultId = entity.id;
          message.resultTitle = entity.title;
          entity.warningMessages.push(message);
          this.warnings.push(message);
        }
      }

    }
  }


  getEmbargoEndDateMessage(result: ClaimEntity) {
    for (let message of result.warningMessages) {
      if (message.type == "embargoEndDate") {
        return "Embargo end date must be later than published date";
      }
    }
    return null;
  }
  updateLocalStorage(){
    if (this.sources != null) {
      localStorage.setItem(this.localStoragePrefix+"sources", JSON.stringify(this.sources));
    }
    if (this.results != null) {
      localStorage.setItem(this.localStoragePrefix+"results", JSON.stringify(this.results));
    }
  }

  goTo(show:string=null) {
    if(show && (['project','context', 'result']).indexOf(show)!=-1){
      this.showOptions.show = show;
      this.showOptions.basketShowSources=false;
      this.showOptions.basketShowLinksTo=true;
    }
    HelperFunctions.scroll();
  }

}
