import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';

import {EnvProperties} from '../../openaireLibrary/utils/properties/env-properties';

import {Session} from '../../openaireLibrary/login/utils/helper.class';
import {LoginErrorCodes} from '../../openaireLibrary/login/utils/guardHelper.class';
import {Curator} from '../../openaireLibrary/utils/entities/CuratorInfo';
import {DomSanitizer, Title} from '@angular/platform-browser';
import {CustomizationOptions} from '../../openaireLibrary/connect/community/CustomizationOptions';
import {StringUtils} from '../../openaireLibrary/utils/string-utils.class';
import {LayoutService} from '../../openaireLibrary/services/layout.service';
import {AlertModal} from '../../openaireLibrary/utils/modal/alert';

@Component({
  selector: 'customization',
  templateUrl: './customization.component.html',
})

export class CustomizationComponent implements OnInit {

  menuSelected = 'main';
  color = 'white';
  publishedCustomizationOptions: CustomizationOptions = null;
  draftCustomizationOptions: CustomizationOptions = null;
  appliedCustomizationOptions: CustomizationOptions = null;
  previewUrl = null;
  previewCustomization = null;
  buttonDarkBackgroundPreview;
  buttonLightBackgroundPreview;
  linkDarkBackgroundPreview;
  linkLightBackgroundPreview;
  hoveredText;
  public showLoading = true;
  public errorMessage = '';
  public successfulSaveMessage = '';


  public communityId = null;

  public properties: EnvProperties = null;

  public enabled = true;
  @ViewChild('backAlert') backAlert: AlertModal;
  @ViewChild('exitAlert') exitAlert: AlertModal;

  constructor(private element: ElementRef,
              private route: ActivatedRoute,
              private _router: Router,
              private title: Title,
              private sanitizer: DomSanitizer,
              private layoutService: LayoutService) {
  }


  ngOnInit() {
    this.route.data.subscribe((data: { envSpecific: EnvProperties }) => {
      this.properties = data.envSpecific;
      if (!Session.isLoggedIn()) {
        this._router.navigate(['/user-info'], {
          queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}
        });
      } else {
        this.route.queryParams.subscribe((params) => {
          this.communityId = params['communityId'];
          this.title.setTitle('Administration Dashboard | Customization');
          this.showLoading = true;
          this.errorMessage = '';
          this.successfulSaveMessage = '';
          this.layoutService.getLayout(this.properties, this.communityId).subscribe(layout => {
            this.publishedCustomizationOptions = (layout?layout:new CustomizationOptions());
            this.initializeCustomizationOptions(true);
          }, error => {
            this.publishedCustomizationOptions = new CustomizationOptions();
            this.initializeCustomizationOptions(true);
            this.errorMessage = "An error occured fetching customizations options"
          });
        });
      }
    });

  }
  hasChanges(object1,object2):boolean{
    return JSON.stringify(object1) != JSON.stringify(object2);
  }
  saveLayout() {
    if (!Session.isLoggedIn()) {
      this._router.navigate(['/user-info'], {
        queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}
      });
    }
    this.layoutService.saveLayout(this.properties, this.communityId, this.draftCustomizationOptions).subscribe(layout => {
      this.publishedCustomizationOptions = layout;
      this.initializeCustomizationOptions(JSON.stringify(this.publishedCustomizationOptions) != this.previewCustomization);
      this.successfulSaveMessage = "Customization Options saved!"
    }, error => {
      this.errorMessage = "An error occured on save"
    });
  }

  initializeCustomizationOptions(updatePreviewUrl) {
    this.draftCustomizationOptions = this.copyObject(this.publishedCustomizationOptions);
    this.appliedCustomizationOptions = this.copyObject(this.publishedCustomizationOptions);

    if(updatePreviewUrl){
      this.previewUrl = this.getCommunityUrlSatinized(JSON.stringify(this.appliedCustomizationOptions));
    }


    this.buttonDarkBackgroundPreview = this.changeStyle(this.draftCustomizationOptions.buttons.darkBackground);
    this.buttonLightBackgroundPreview = this.changeStyle(this.draftCustomizationOptions.buttons.lightBackground);
    this.linkDarkBackgroundPreview = this.changeFontsStyle(this.draftCustomizationOptions.links.darkBackground, this.draftCustomizationOptions.links.darkBackground.color);
    this.linkLightBackgroundPreview = this.changeStyle(this.draftCustomizationOptions.links.lightBackground, this.draftCustomizationOptions.links.lightBackground.color);
  }

  applyLayout() {
    this.appliedCustomizationOptions = this.copyObject(this.draftCustomizationOptions);
    if(JSON.stringify(this.appliedCustomizationOptions) != this.previewCustomization){
      this.previewUrl = this.getCommunityUrlSatinized(JSON.stringify(this.appliedCustomizationOptions));
    }
  }

  resetLayout() {

    if (this.menuSelected == 'backgrounds') {
      this.resetBackgrounds();
    } else if (this.menuSelected == 'fonts') {
      this.resetFonts();
    } else if (this.menuSelected == 'elements') {
      this.resetElements();
    } else if (this.menuSelected == 'buttons') {
      this.resetButtons();
    } else if (this.menuSelected == 'identity') {
      this.resetIdentity();
    } else {
      this.draftCustomizationOptions = this.copyObject(this.publishedCustomizationOptions);

      this.appliedCustomizationOptions = this.copyObject(this.publishedCustomizationOptions);
    }
    // console.log(JSON.stringify(this.appliedCustomizationOptions))
    // console.log(this.previewCustomization)
    this.initializeCustomizationOptions(JSON.stringify(this.appliedCustomizationOptions) != this.previewCustomization);

  }

  resetBackgrounds() {
    this.draftCustomizationOptions.panel.onDarkBackground = this.publishedCustomizationOptions.panel.onDarkBackground;
    this.draftCustomizationOptions.panel.background.color = this.publishedCustomizationOptions.panel.background.color;

    this.appliedCustomizationOptions.panel.onDarkBackground = this.publishedCustomizationOptions.panel.onDarkBackground;
    this.appliedCustomizationOptions.panel.background.color = this.publishedCustomizationOptions.panel.background.color;
  }

  resetFonts() {
    this.resetFontsBig();
    this.resetFontsSmall();
    this.resetFontsLinksDark();
    this.resetFontsLinksLight();

  }

  resetFontsBig() {
    this.draftCustomizationOptions.panel.title = this.copyObject(this.publishedCustomizationOptions.panel.title);

    this.appliedCustomizationOptions.panel.title = this.copyObject(this.publishedCustomizationOptions.panel.title);
  }

  resetFontsSmall() {
    this.draftCustomizationOptions.panel.fonts = this.copyObject(this.publishedCustomizationOptions.panel.fonts);

    this.appliedCustomizationOptions.panel.fonts = this.copyObject(this.publishedCustomizationOptions.panel.fonts);


  }

  resetFontsLinksDark() {
    this.draftCustomizationOptions.links.darkBackground = this.copyObject(this.publishedCustomizationOptions.links.darkBackground);

    this.appliedCustomizationOptions.links.darkBackground = this.copyObject(this.publishedCustomizationOptions.links.darkBackground);

    this.linkDarkBackgroundPreview=this.changeFontsStyle(this.publishedCustomizationOptions.links.darkBackground, this.publishedCustomizationOptions.links.darkBackground.color);
  }

  resetFontsLinksLight() {
    this.draftCustomizationOptions.panel.title = this.copyObject(this.publishedCustomizationOptions.panel.title);
    this.draftCustomizationOptions.links.lightBackground = this.copyObject(this.publishedCustomizationOptions.links.lightBackground);

    this.appliedCustomizationOptions.panel.title = this.copyObject(this.publishedCustomizationOptions.panel.title);
    this.appliedCustomizationOptions.links.lightBackground = this.copyObject(this.publishedCustomizationOptions.links.lightBackground);

    this.linkLightBackgroundPreview=this.changeFontsStyle(this.publishedCustomizationOptions.links.lightBackground, this.publishedCustomizationOptions.links.lightBackground.color);
  }

  resetElements() {
    this.draftCustomizationOptions.panel.panelElements = this.copyObject(this.publishedCustomizationOptions.panel.panelElements);

    this.appliedCustomizationOptions.panel.panelElements = this.copyObject(this.publishedCustomizationOptions.panel.panelElements);
  }

  resetButtons() {
    this.resetButtonsDark();
    this.resetButtonsLight();
  }

  resetButtonsDark() {
    this.draftCustomizationOptions.buttons.darkBackground = this.copyObject(this.publishedCustomizationOptions.buttons.darkBackground);

    this.appliedCustomizationOptions.buttons.darkBackground = this.copyObject(this.publishedCustomizationOptions.buttons.darkBackground);

    this.buttonDarkBackgroundPreview=this.changeStyle(this.publishedCustomizationOptions.buttons.darkBackground);
  }

  resetButtonsLight() {
    this.draftCustomizationOptions.buttons.lightBackground = this.copyObject(this.publishedCustomizationOptions.buttons.lightBackground);

    this.appliedCustomizationOptions.buttons.lightBackground = this.copyObject(this.publishedCustomizationOptions.buttons.lightBackground);

    this.buttonLightBackgroundPreview=this.changeStyle(this.publishedCustomizationOptions.buttons.lightBackground);
  }

  resetIdentity() {
    this.draftCustomizationOptions.mainColor = this.publishedCustomizationOptions.mainColor;
    this.draftCustomizationOptions.secondaryColor = this.publishedCustomizationOptions.secondaryColor;

    this.appliedCustomizationOptions.mainColor = this.publishedCustomizationOptions.mainColor;
    this.appliedCustomizationOptions.secondaryColor = this.publishedCustomizationOptions.secondaryColor;
  }

  changeStyle(colorOptions, borderOptions = null) {
    let style = '';
    if (!borderOptions) {
      borderOptions = colorOptions;
    }
    if (colorOptions.color) {
      style = style.concat('; color:' + colorOptions.color);
    }
    if (colorOptions.backgroundColor) {
      style = style.concat( '; background-color:' + colorOptions.backgroundColor);
    }
    if (colorOptions.borderColor) {
      style = style.concat('; border-color:' + colorOptions.borderColor);
    }
    if (borderOptions.borderStyle) {
      style = style.concat('; border-style:' + borderOptions.borderStyle);
    }
    if (borderOptions.borderWidth) {
      style = style.concat( '; border-width:' + borderOptions.borderWidth + 'px');
    }
    if (borderOptions.borderRadius) {
      style = style.concat('; border-radius:' + borderOptions.borderRadius + 'px');
    }

    return this.sanitizer.bypassSecurityTrustStyle(style);
  }


  changeFontsStyle(options, color = null) {
    let style = '';


    if (options.family) {
      style = style.concat('; font-family:' + options.family);
    }

    if (options.size) {
      style = style.concat('; font-size:' + options.size + 'px');
    }

    if (options.weight) {
      style = style.concat('; font-weight:' + options.weight);
    }

    if (color) {
      style = style.concat('; color:' + color);
    }

    return this.sanitizer.bypassSecurityTrustStyle(style);
  }

  getCommunityUrlSatinized(layout: string) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(this.getCommunityUrlNewLayout(layout));
  }
  getCommunityUrl() {
    return 'https://'+ (this.properties.environment == 'production'?'':'beta.')+this.communityId+'.openaire.eu';
  }

  getCommunityUrlNewLayout(layout: string) {
    this.previewCustomization = layout;
      return this.getCommunityUrl()+'/?' + 'layout=' + StringUtils.URIEncode(layout);
  }

  copyObject(obj) {
    return JSON.parse(JSON.stringify(obj));
  }

  back() {
    if (JSON.stringify(this.draftCustomizationOptions) == JSON.stringify(this.publishedCustomizationOptions) ||
      JSON.stringify(this.draftCustomizationOptions) == JSON.stringify(this.appliedCustomizationOptions)) {
      this.menuSelected = 'main';
    } else {
      this.backAlert.okButtonText = 'Yes';
      this.backAlert.cancelButtonText = 'No';
      this.backAlert.alertTitle = '';
      this.backAlert.okButtonLeft = true;
      this.backAlert.open();
    }

  }

  resetToAppliedOptions() {
    this.draftCustomizationOptions = this.copyObject(this.appliedCustomizationOptions);
    this.menuSelected = 'main';
  }

  exit() {
    if (JSON.stringify(this.appliedCustomizationOptions) == JSON.stringify(this.publishedCustomizationOptions)) {
      this.exitCustomization();
    } else {
      this.exitAlert.okButtonText = 'Yes';
      this.exitAlert.cancelButtonText = 'No';
      this.exitAlert.alertTitle = '';
      this.exitAlert.okButtonLeft = true;
      this.exitAlert.open();
    }

  }

  exitCustomization() {
    this._router.navigate(['/dashboard'], {
      queryParams: {'communityId': this.communityId}
    });
  }
  downloadCustomization(){
    this.errorMessage = "";
    let options= JSON.parse(JSON.stringify(this.publishedCustomizationOptions));
    delete options['_id'];
    console.info("Here!" +JSON.stringify(options));
    if(typeof document !== 'undefined') {
      let dataStr = JSON.stringify(options);
      let dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);

      let exportFileDefaultName = 'layoutOptions.json';

      let linkElement = document.createElement('a');
      linkElement.setAttribute('href', dataUri);
      linkElement.setAttribute('download', exportFileDefaultName);
      linkElement.click();
    }
  }
  fileChangeEvent(fileInput: any) {
    this.errorMessage = "";
     let filesToUpload = <Array<File>>fileInput.target.files;


      if (filesToUpload.length == 0) {
        this.errorMessage = "There is no selected file to upload.";
        return;
      } else {
        if (filesToUpload[0].name.indexOf(".json") == -1 ||
          (filesToUpload[0].type != "application/json" )) {
          this.errorMessage = "No valid file type. The required type is json "+filesToUpload[0].type;
          return;
        }
      }

      this.makeFileRequest(this.properties.utilsService + '/upload?type=json', [], filesToUpload).then((result) => {
       let layout:CustomizationOptions = JSON.parse(result.toString());
        if( layout && layout.panel && layout.links && layout.buttons && layout.box){
          this.draftCustomizationOptions = layout;
          //put the same id to not have any difference
          if(this.publishedCustomizationOptions['_id']){
            this.draftCustomizationOptions['_id'] = this.publishedCustomizationOptions['_id'];
          }
        }else{
          this.errorMessage = "No valid file";
        }

      }, (error) => {
        this.errorMessage = "No valid file";
      });
    }


  makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
    return new Promise((resolve, reject) => {
      const formData: any = new FormData();
      const xhr = new XMLHttpRequest();
      for (let i = 0; i < files.length; i++) {
        formData.append("uploads[]", files[i], files[i].name);
      }
      xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
          if (xhr.status == 200) {
            resolve(xhr.response);
          } else {
            reject(xhr.response);
          }
        }
      }
      xhr.open("POST", url, true);
      xhr.send(formData);
    });
  }




}
