import {Injectable, OnDestroy} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {UserService, AppConfigService, Session} from "@webbpm/base-package";
import {
  JivoProfileDto
} from "../../../generated/dto/jivoprofile/JivoProfileDto";
import {Observable, Subscription} from "rxjs";

declare function jivo_InitProfile(name, email, phone);

declare function jivo_ClearHistory();

@Injectable()
export class AppJivoChatWidgetService implements OnDestroy {

  public static LIVE_CHAT_WIDGET_API_URL: string = "jivo_chat_widget_api_url";
  public static LIVE_CHAT_WIDGET_ENABLE: string = "jivo_chat_widget_enabled";
  public static LIVE_CHAT_WIDGET_DEFAULT_VALUE: boolean = false;

  private JIVO_CSS: string = `
/* hide the original widget - that there were no two labels on the screen*/
#jivo_chat_widget{
  display: none;
}

/* the default style - for offline messages if no one is online */
#jivo_custom_widget{
  position: fixed;
  z-index: 300000;
  cursor: pointer;

  display: block;
  right: 60px;
  bottom: 10px;

  width: 60px;
  height: 60px;
  background-image: url('data:image/png;base64,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');
  background-size: 60px 60px;
  background-repeat: no-repeat;
}

#jivo_custom_widget:hover{
  bottom: 13px;
}

/* if there are operators online - show other label*/
#jivo_custom_widget.jivo_online{
  height: 60px;
  width: 60px;
  background-size: 60px 60px;
  background-repeat: no-repeat;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAI/ElEQVR4nO2cbXBU1RnH/8+5m2wgAoLYZDcJbHZj2wGsOMzIlFYFx1K0hal0ygdnqtNOlbYfmJpkE8SXWYug7CaIzPiBtjNtx9FBnFoS6ehYUcCClharCB3B3Wxe7yaAYG0DSfbe8/RDsBNSAvfe3Lt52fP7kmT3f57nufe/59yce88eQKFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBTjBBrrAiyzi7WKdEdJAXxBFhwQLGZCcBEDU8BcBAAg6iPgAiT1SZLnSFImC0PvqKzowRoyx/gILDEuDZmb6K70wVwMphslYT4YNxJhLgDNYUiTGW0gfCQYxwE+aprir60PB1rdrNsNxoUhVZsz10ufXElESxlYCqAiR6nbCdjP4LdFVuxJbgiczlHeERkzQyq39ZSIAWONJFpNwK1w/ul3CxOEA8z8ioC2KxUtPTUWReTckEiDvkhKPEiE+wAU5Tq/RQaI0MTMv2qpDe4FEecqcW4MYaZwIrMaRI8D/LWc5HSPDwl4IlUb2J0LYzw3pLKxaxVJsXECGjGcD8Hi0Za60j1eJvHMkKotneVSiG0Avu9VjjGBeI/J2rq2aGnai/DC9YjMVNmQqZFCnMBkMwMAmL6rQR4LJ/RqMLv+gXY14Jcb9NkG43cAvuNm3HHMm5J9P2yt+1K3WwFdMyTSoC8CUzODg27FnCB0CcErkzVl/3AjmCtDViTRfQcz3spDMwCgTEo6EInrK9wINmpDIgn9HoZ8DcB0F+qZqFzDhKbKxq5Vow00qiErFM/cLohfx/id4OWaPmYsT9cF33EawLEhVQ2ZeZL5EIAZTmNMUs5JwpLW2uDHTho7GrKqtn/il8wvQplxOWYKxsuhWNrRqOHIELO/OA7gJidt84QFotj/lJOGtoesULxzoSBxBF5MKicXkgi3pGqDR+w0sn1SBYmEk3Z5iGAgYbuRHXEk0X0HgDvtJslbGMtC8cztdprYMkQSP2ivIoUAP2BHb/kaUr61Y1ahqXVBzTns0mcY2WD7w3PPWRFb7iF+UyyHt2ZkwfxLIWXFlN5zfpa0GMCBK+i7QXyv8PtnFMiC6cy0BkDXSGJifo8Ef0P4e4uy0ihj4FEA/W4fxGUo0nyF37Iq9lkVShJLiL17YCbAP0jWlTUBAGIsUE+HEeNl4eLu3QCvHKpl4FNDGos66ufoYCY8AUKMXq7anNknC/gogNJh4d9MhYIrsIZMxFggRjqATZVx/W9EeB0eP6gj5iUAdlnRWu4hBF7suKKrxWZqTkbLmiKNXRXhhP5BuDjTF47rWxEj6dOMnwEwh+kf66ifo4fjmbvDDZlT4eLMmXCDvjq5IXCaiNYPC8+CtZ9iDZmRhP5kuDhzIZzQj1fFeyLpuuAbAL3k1XH9r14b5866IUzlzsq5Okz8NgCwpGoMTjgLQHio6unM/JPVFV0ATgzVm8z7LhbVCGA2gJlgbAMANgZjDaE9WVeSCj2VCTHwCIBCAPOYzHoAIPo/veswkeVlTZYNYfB1zsqxFN1/8ee/hrxomj7+z8Xf/UPVRPKLv4fqB38X5iXaL9pqPjoPIDsk56Be8nC9F1g+d5YMWbSDCzDspLgJMb6HGIsCWdjIwO8BHAH4gXRtsC0U71wIIDJUL0D3AABB/ARMewnYLxj3DwYTq4eFL61KdH49FS09BeL7AfwdwItZw9gMZmIxGMtjii6ew6ti+WIWTuifwdubiRtaosFL7v+EnklfS4b/LQJuHqbtl0Isba0pfW/oi1WNXTdLSX8BMHWY/p+FWXnbxxvKPx36YiShr2PgWdeOYGR6W6LBa6wI7RhyEsANjkuyADE1M+jXknBag1zIwGMAykaQZxm8jVn8iQQzMVYAqMbIPbkbRBsl0fvC5Fkg/jFytwijrSUaDFkRWjYkktD3MWDrNoBiEAb2paPBZVa0li/qkuH4KVi+I4CDNrSWlX92VI0CDHrXqtayIbOmBd4F8LmjivKbs7K3b69VsWVDjqylLIDfOCopj2GiF1pjlX1W9fYeNJl4FpdMrhRXQWoGdthpYMuQlvXBdgJ22qspf2Hg+eT6wHE7bWw/ijV8BfUALN3bz3MukInH7TaybUjbQ9dnAK6x2y7fIOb6lvXBdtvtHGVjpnBD5lXkzyp3exDvaakJrnLyjStnq0eIWPj99wJ01FH7yc1JH+hHTr/+5ng5T3LddZ9nZfYuAB1OY0w2CKRLg759sjZ4xmmMUa2v6qifoxPE3QTSRxNnUsDokTDuGu1mBKNe8JaKlh7TNOOWPB++0oB5azpaMepz4NrD/YvLhJoAfNOtmBOEgwSx2q2NBlxbEtpZXXF2Tm9gGcDrkR+zeWZg+8zpgWVu7vrgyfKXSGPXEmnS80QIexF/HJBm4rXp2jLX74B7smg6VVN2aGqx7yYCNgE470WOMaKfGU8OaOZ8L8wAcrCTQ9WWznKp0UYw3YeJu2reYOAFjbWNybqSlJeJcrb5TCSur2DCa7nK5xL9DOwkNje11FV8kouElpeSjj6TmYQ51jswWYMZLQK8gwzx21zvoZUzQ9jQfj4+tksbkXYAr4Dwh3Rv4BBiJMeiiJycotAz6WuF4W8HMC0X+SzyGUDvMGG/AO9L1QTez+W+WCORkx6iGYWPsH0zTjLTdoBLiRAm5jCDKkEosRnnNBjdICQZOAamjyTzsbYLgROX9IJam1E9wvv/suI9EUnmcdhbinqMC7Q7078o6Rn+RjCmTy0qwmwUyCJiMY2YpjFhCksQSA5IaP/WSBoSOKMV9nYn192Qi++AuIbnPYQht8KeGR+ILC1PRksuezHVY8HzGBzvJyWezgsiCX0tE9vZ/+OPMIuWjofdQccKz4asSKJ7AUMeBjDFgryXmerTdYHnvKpnouBJDwk/fXYGQ74ES2bQTiHlV5UZg7h+DSnf2jEFZl8zgHlXkA0QoUma1JCuDxx2u4aJjKuGfGXL6WlZc2A3gNsu8/YpAAeJqbnfZzR3VlecdTP3ZMFVQ0zRvwAQrwL8BkBZYjrLmtkhB7TUeNxnXaFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBSKK/Bf/RI0U2U6gOkAAAAASUVORK5CYII=');
}`;

  private JIVO_JS: string = `
/* Callback function that is called immediately after JivoChat is loaded */
function jivo_onLoadCallback() {
  window.jivo_cstm_widget = document.createElement('div');
  jivo_cstm_widget.setAttribute('id', 'jivo_custom_widget');
  document.body.appendChild(jivo_cstm_widget);

  /* Adds handlers click on the icon - to maximize the window when clicked */
  jivo_cstm_widget.onclick = function () {
    jivo_api.open();
  }

  /* Change the CSS class if there are agents online */
  if (jivo_config.chat_mode === "online") {
    jivo_cstm_widget.setAttribute("class", "jivo_online");
  }

  /* Show the user a shortcut */
  window.jivo_cstm_widget.style.display = 'block';
}

/*
 Callback function jivo_onOpen and jivo_onClose called whenever the chat window JivoChat
  is expanded or collapsed by the user or by the proactive invitations rule.
*/
function jivo_onOpen() {
  /* If chat is deployed - hide shortcut */
  if (jivo_cstm_widget)
    jivo_cstm_widget.style.display = 'none';
}

function jivo_onClose() {
  /* If chat is minimized - show label */
  if (jivo_cstm_widget)
    jivo_cstm_widget.style.display = 'block';
}

function jivo_ClearHistory() {
  jivo_api.clearHistory();
  jivo_api.close();
}

function jivo_InitProfile(name, email, phone) {
  let chatMode = jivo_api.chatMode();

  let args = {
    name: name ? name : '',
    email: email ? email : '',
    phone: phone ? phone : ''
  };

  if (chatMode === 'offline') {
    jivo_api.sendOfflineMessage(args);
  }
  else {
    jivo_api.setContactInfo(args);
  }
}
`;

  private currentUserName: string;
  private currentEmail: string;
  private currentPhone: string;

  private jsLoaded = false;
  private jivoWidgetApiUrl: string;

  private currentSession: Observable<Session>;
  private currentSessionSubscription: Subscription;
  private session: Session;
  private sessionInitJivoChatWidget: boolean;

  constructor(private httpClient: HttpClient,
              private appConfigService: AppConfigService,
              private userService: UserService) {

    this.currentSession = userService.getCurrentSession();
    this.currentSessionSubscription =
        this.currentSession.subscribe(val => {

      if (!this.sessionInitJivoChatWidget || !this.session) {
        this.initJivoChatWidget();
        this.sessionInitJivoChatWidget = true;
      }

      if (this.session && !val) {
        // logout
        this.clearJivoProfile();
        this.session = null;
        this.sessionInitJivoChatWidget = false;
      }

      if (val) {
        this.session = val;
      }
    });
  }

  private initJivoChatWidget() {
    let liveChatWidgetEnabled = this.getValueFromAppConfig(
        AppJivoChatWidgetService.LIVE_CHAT_WIDGET_ENABLE,
        AppJivoChatWidgetService.LIVE_CHAT_WIDGET_DEFAULT_VALUE);

    if (liveChatWidgetEnabled) {
      this.jivoWidgetApiUrl = this.getValueFromAppConfig(
          AppJivoChatWidgetService.LIVE_CHAT_WIDGET_API_URL,
          '');

      if (!this.jivoWidgetApiUrl) {
        throw new Error(
            `The configuration file does not contain the 'Jivo API url'. Please check that '${AppJivoChatWidgetService.LIVE_CHAT_WIDGET_API_URL}' has data`);
      }

      let userId = this.userService.getCurrentUserId();
      if (userId) {
        this.clearJivoProfile();
        this.httpClient.get('profile/jivo/' + userId)
            .toPromise()
            .then((profile: JivoProfileDto) => {

              this.currentUserName = profile.username;
              this.currentEmail = profile.email;
              this.currentPhone = profile.phone;

              let initProfileFunction = () => this.initProfile(this.currentUserName,
                                                               this.currentEmail,
                                                               this.currentPhone);
              this.loadScripts(initProfileFunction);
            });
      }
      else {
        let initProfileFunction = () => this.initProfile(this.currentUserName, this.currentEmail,
                                                         this.currentPhone);
        this.loadScripts(initProfileFunction);
      }
    }
  }

  private clearJivoProfile() {
    this.clearProfileData();
    try {
      jivo_ClearHistory();
    }
    catch (ignore) {
    }
  }

  private clearProfileData() {
    this.currentUserName = '';
    this.currentEmail = '';
    this.currentPhone = '';
  }

  private loadScripts(initProfileFunction): void {
    let afterLoadMainJs = () => {
      this.loadScriptJsContent('jivoCustomJs', this.JIVO_JS, initProfileFunction);
    }
    this.loadScript('jivoWidget', this.jivoWidgetApiUrl, true, afterLoadMainJs);
    this.loadStyleContent('jivoCustomCss', this.JIVO_CSS);
  }

  private initProfile(username: string, email: string, phone: string): void {
    try {
      jivo_InitProfile(username, email, phone);
    }
    catch (e) {
      if (e instanceof ReferenceError) {
        if (!this.jsLoaded) {
          this.jsLoaded = true;
          setTimeout(() => {
            jivo_InitProfile(username, email, phone);
          }, 3000);
        }
      }
    }
  }

  private loadScript(elementId, js, async, callback): void {
    let jivoJsLink = document.getElementById(elementId);
    if (!jivoJsLink) {
      let node = document.createElement('script');
      node.src = js;
      node.type = 'text/javascript';
      node.id = elementId;
      node.async = async;
      node.charset = 'utf-8';
      if (callback) {
        node.onload = function () {
          callback();
        };
      }
      document.getElementsByTagName('head')[0].appendChild(node);
    }
    else {
      if (callback) {
        callback();
      }
    }
  }

  private loadScriptJsContent(elementId, js, callback): void {
    let jivoJs = document.getElementById(elementId);
    if (!jivoJs) {
      let node = document.createElement('script');
      node.innerHTML = js;
      node.type = 'text/javascript';
      node.id = elementId;
      node.charset = 'utf-8';
      if (callback) {
        callback();
      }
      document.getElementsByTagName('head')[0].appendChild(node);
    }
    else {
      if (callback) {
        callback();
      }
    }
  }

  private loadStyleContent(elementId, styleCss): void {
    let jivoCss = document.getElementById(elementId);
    if (!jivoCss) {
      const style = document.createElement('style');
      style.id = elementId;
      style.innerHTML = styleCss;
      document.getElementsByTagName('head')[0].appendChild(style);
    }
  }

  private getValueFromAppConfig(key, defaultValue) {
    let enabled = this.appConfigService.getParamValue(key);
    if (enabled === undefined) {
      return defaultValue;
    }
    return enabled;
  }

  ngOnDestroy(): void {
    this.currentSessionSubscription.unsubscribe();
  }

}
