/**
 *
 */
'use strict';
define(function() {
  var gcPopup = function() {
    this.$get = function($compile, $http, $rootScope, $timeout, dialogsCommon, $window) {
      var Popup = function(options) {
        this.popup = options.scope.$new(false);
        this.popup.options = options;
        this.popup.scope = options.scope;
        this.popup.isMaximized = false;
        this.popup.isTab = false;
        this.popup.position = options.position;
        this.popup.resizeEnabled = false;
        this.popup.popupStates = {};
        this.popup.boundings = {};
        this.popup.topOffset = null;
        this.popup.iddiv = generateUniqueId();
        this.popup.className = options.className;
        this.popup.minHeight = options.minHeight;
        this.popup.minWidth = options.minWidth;

        $http
          .get('js/XG/modules/common/views/gcPopupTemplate.html')
          .then(template => {
            var element = angular.element(template.data);
            const popupElement = $compile(element)(this.popup);

            $(document.body).append(popupElement);

            $timeout(() => {
              // wait until the template draw is over
              const popupElement = $(`div[ga-draggable-zone='#${this.popup.iddiv}zone']`);
              if (popupElement) {
                let titleWidth = popupElement.find('.popupName').outerWidth() + 118;

                // dimensionne le titre avec du style inline uniquement
                // si l'option noResizeTitlebar est absente
                // permet d'éviter le très mauvais calcul de largeur et
                // le sale ajout de style inline
                if (!options.noResizeTitlebar) {
                  popupElement.css({ 'min-width': titleWidth  + 'px'});
                }
                // ajoute la possibilité de fixer une largeur minimale à la popup
                if (options.minWidth) {
                  popupElement.css({ 'min-width': options.minWidth + 'px' });
                }

                if (!options.maxWidth) {
                  this.popup.options.maxWidth = $window.innerWidth - 50;
                }
                if (!options.maxHeight) {
                  this.popup.options.maxHeight = $window.innerHeight - 50;
                }
              }

              setPopupPosition(popupElement, this.popup.position);

              if (options.content) {
                var contentElement = angular.element(options.content);
                let compiledContentElement = $compile(contentElement)(
                  this.popup.scope
                );

                let popupContentElement = popupElement.find('.popupContent');
                popupContentElement.append(compiledContentElement);
              }
            });
          });


        this.popup.maximize = () => {
          if (this.popup.isTab) {
            this.popup.savePopupState('minimized');
          }
          else {
            this.popup.savePopupState('normal');
          }

          const popupElement = $(`div[ga-draggable-zone='#${this.popup.iddiv}zone']`);

          let leftMenu = $('.mapLeftMenu');
          let leftMenuCoordinates = {};
          let displayFirstLevelBoundings = $(
            '.displayFirstLevel'
          )[0].getBoundingClientRect();
          let mapMenuWrapperBoundings = $(
            '.mapMenuWrapper'
          )[0].getBoundingClientRect();

          if (leftMenu.find('.mapMenuWrapper').hasClass('active')) {
            leftMenuCoordinates.right = mapMenuWrapperBoundings.right;
            leftMenuCoordinates.width =
              displayFirstLevelBoundings.width + mapMenuWrapperBoundings.width;
          }
          else {
            leftMenuCoordinates.right = displayFirstLevelBoundings.right;
            leftMenuCoordinates.width = displayFirstLevelBoundings.width;
          }

          popupElement.find('.panel-collapse').show();

          let popupProps = {
            top: 0,
            left: leftMenuCoordinates.right,
            width: `calc(100vw - ${leftMenuCoordinates.width}px)`,
            height: '100vh',
          };
          let popupContentProps = {
            height: 'auto',
            width: 'auto',
          };

          this.popup.updateProperties(popupProps, popupContentProps);
          this.popup.isTab = false;
          this.popup.isMaximized = true;
          this.popup.resizeEnabled = false;
        };

        this.popup.normalize = () => {
          if (this.popup.isTab) {
            this.popup.savePopupState('minimized');
          }

          let popupProps = {
            top: this.popup.popupStates.normal.popupProperties.top,
            left: this.popup.popupStates.normal.popupProperties.left,
            width: this.popup.popupStates.normal.popupProperties.width,
            height: this.popup.popupStates.normal.popupProperties.height,
            'min-height': this.popup.popupStates.normal.popupProperties.minHeight
          };

          let popupContentProps = {
            height: this.popup.popupStates.normal.popupContentProperties.height,
            width: this.popup.popupStates.normal.popupContentProperties.width,
          };

          this.popup.updateProperties(popupProps, popupContentProps);
          this.popup.isTab = false;
          this.popup.isMaximized = false;
          this.popup.resizeEnabled = true;
        };

        this.popup.makeItTab = () => {
          if (!this.popup.isMaximized && !this.popup.isTab) {
            this.popup.savePopupState('normal');
            this.popup.savePopupState('minimized');
          }

          const popupElement = $(`div[ga-draggable-zone='#${this.popup.iddiv}zone']`);

          if (this.popup.isTab) {
            // make it normal
            popupElement.find('.panel-collapse').show();
            this.popup.normalize();
            this.popup.isTab = false;
          }
          else {
            // make it tab
            popupElement.find('.panel-collapse').hide();
            let tittleWidth = popupElement.find('.popupName').outerWidth() + 118;
            popupElement.css({
              top: this.popup.popupStates.normal.popupProperties.top,
              left: this.popup.popupStates.normal.popupProperties.left,
              height: 'auto',
              width: tittleWidth,
              'min-height': 'unset'
            });
            this.popup.isTab = true;
          }

          this.popup.isMaximized = false;
          this.popup.resizeEnabled = false;
        };

        this.popup.updateProperties = (popupProps, popupContentProps) => {
          const popupElement = $(`div[ga-draggable-zone='#${this.popup.iddiv}zone']`);
          popupElement.css({
            top: popupProps.top,
            left: popupProps.left,
            width: popupProps.width,
            height: popupProps.height,
          });

          popupElement.find('.popupContent').css({
            height: popupContentProps.height,
            width: popupContentProps.width,
          });
        };

        this.popup.savePopupState = state => {
          const popupElement = $(`div[ga-draggable-zone='#${this.popup.iddiv}zone']`);
          let popupContent = $('.popupContent');
          let popupBoundings = popupElement[0].getBoundingClientRect();
          let popupPosition = popupElement.position();

          // la hauteur minimale altère la minimization, on la sauvegarde avant de la retirer
          const popupMinHeight = Number.parseInt(popupElement.css("min-height"));

          this.popup.popupStates[state] = {
            popupProperties: {
              top: popupPosition.top,
              left: popupPosition.left,
              width: popupBoundings.width,
              height: popupBoundings.height,
              minHeight: popupMinHeight
            },
            popupContentProperties: {
              width: popupContent.outerWidth(),
              height: popupContent.outerHeight(),
            },
          };
        };

        this.popup.close = _uniqueID => {
          $('#' + _uniqueID).remove();
          this.popup.removeEvents();
          $rootScope.$broadcast('closeDraggable', {
            id: angular.isDefined(this.id) ? this.id : _uniqueID,
          });
          if (this.popup.options.onclose) this.popup.options.onclose();
        };

        this.popup.resize = event => {
          const popupElement = $(`div[ga-draggable-zone='#${this.popup.iddiv}zone']`);
          let isFocused = popupElement.attr('focusedPopup') === 'true';

          if (!isFocused) {
            return;
          }

          let popupBoundings = popupElement[0].getBoundingClientRect();
          let mousePosition = { left: event.clientX, top: event.clientY };
          $('body').css({ 'user-select': 'none' });

          switch (this.popup.resizeSide) {
            case 'topResize': {
              let popupIncrement = popupBoundings.top - mousePosition.top;
              let newPopupHeight = popupElement.height() + (popupBoundings.top - mousePosition.top);

              // empêche le redimensionnement en dessous de la hauteur minimale personnalisée
              if (this.popup.minHeight > 0 && newPopupHeight < this.popup.minHeight) {
                newPopupHeight = this.popup.minHeight;
              }

              popupElement.height(newPopupHeight);
              popupElement.css({
                top: popupElement.position().top - popupIncrement,
              });

              // ajuste la hauteur de la div '.popupContent' après redimensionnement de son conteneur
              const popupContent = popupElement.find('.popupContent');
              if (popupContent !== null) {
                popupContent.css({
                  height: '100%'
                });
              }

              $('body').css({ cursor: 'n-resize' });
              break;
            }
            case 'rightResize': {
              let newPopupWidth = popupElement.width() + mousePosition.left - popupBoundings.right;
              popupElement.width(newPopupWidth);

              // ajuste la largeur de la div '.popupContent' après redimensionnement de son conteneur
              const popupContent = popupElement.find('.popupContent');
              if (popupContent !== null) {
                popupContent.css({
                      width: '100%'
                });
              }
              $('body').css({ cursor: 'e-resize' });
              break;
            }
            case 'bottomResize': {
              let newPopupHeight = popupElement.height() + mousePosition.top - popupBoundings.bottom;

              // empêche le redimensionnement en dessous de la hauteur minimale personnalisée
              if (this.popup.minHeight > 0 && newPopupHeight < this.popup.minHeight) {
                newPopupHeight = this.popup.minHeight;
              }

              popupElement.height(newPopupHeight);

              // ajuste la hauteur de la div '.popupContent' après redimensionnement de son conteneur
              const popupContent = popupElement.find('.popupContent');
              if (popupContent !== null) {
                popupContent.css({
                  height: '100%'
                });
              }

              $('body').css({ cursor: 'n-resize' });
              break;
            }
            case 'leftResize': {
              let popupIncrement = popupBoundings.left - mousePosition.left;
              let newPopupWidth = popupElement.width() + (popupBoundings.left - mousePosition.left);

              popupElement.width(newPopupWidth);
              popupElement.css({
                left: popupElement.position().left - popupIncrement,
              });

              // ajuste la largeur de la div '.popupContent' après redimensionnement de son conteneur
              const popupContent = popupElement.find('.popupContent');
              if (popupContent !== null) {
                popupContent.css({
                  width: '100%'
                });
              }
              $('body').css({ cursor: 'e-resize' });
              break;
            }
          }
        };

        this.popup.startResize = event => {
          if (
            !this.popup.isMaximized &&
            !this.popup.isTab &&
            $(event.target).hasClass('resizeSide')
          ) {
            this.popup.resizeSide = $(event.target)
              .attr('class')
              .split(' ')[1];
          }
        };

        this.popup.finishResize = () => {
          $('body').css({ cursor: 'auto' });
          this.popup.resizeSide = null;
        };

        this.popup.toggleResize = (event, state) => {
          this.popup.resizeEnabled = state;
        };

        this.popup.activateDrag = event => {
          let eventTarget = $(event.target).hasClass('resizeSide');
          if (!eventTarget) {
            this.popup.resizeEnabled = false;
          }
        };

        this.popup.checkElement = event => {
          let isHeader =
            $(event.target).closest('.headerpopup').length ||
            $(event.target).hasClass('headerpopup');
          this.popup.isHeader = !!isHeader;
        };

        this.popup.dragPopup = (popupElement, left, top) => {

          const popupWidth = parseInt(popupElement.css('width'));
          let newLeft = left;
          let newTop = top;

          //left
          if (left < 0) {
            newLeft = 0;
          }
          //right
          if (left + popupWidth > window.innerWidth) {
            newLeft = window.innerWidth - popupWidth;
          }
          //top
          if (top < 0) {
            newTop = 0;
          }
          //bottom
          if (top + 44 > window.innerHeight) {
            newTop =  window.innerHeight-44; // 44 is the popup label's height
          }

          popupElement.css({
            left: newLeft,
            top: newTop
          });
        };

        this.popup.makeItFocused = () => {
          $timeout(function() {
            if(event){
              $(event.target)
                .closest('.popupContainer')
                .css('z-index', dialogsCommon.getMaxIndex() + 1);
            }
          });

          $('.popupPanel').attr('focusedPopup', false);

          if(event){
            $(event.target)
              .closest('.popupPanel')
              .attr('focusedPopup', true);
          }
        };

        this.popup.makeItFocused();

        if (this.popup.options.resizable) {
          $(document).on('mousemove', this.popup.resize);
          $(document).on('mousedown', this.popup.startResize);
          $(document).on('mouseup', this.popup.finishResize);
        }

        this.popup.removeEvents = () => {
          if (this.popup.options.resizable) {
            $(document).off('mousemove', this.popup.resize);
            $(document).off('mousedown', this.popup.startResize);
            $(document).off('mouseup', this.popup.finishResize);
          }
        };

        function generateUniqueId() {
          const uniqueID = new Date();
          const myRandom = Math.floor(Math.random() * 1000);
          return uniqueID.getTime() + '' + myRandom;
        }

        function setPopupPosition(popup, position) {
          const pos = Object.assign({
            top: 0,
            left: 0,
          }, position);
          popup.css({
            top: pos.top,
            left: pos.left,
          });
        }

        /**
         * Style de la popup à l'initialisation d'après la configuration de l'utilisateur
         * @type {{"max-height": string, "max-width": string, width: (string|string), "min-height": string, "min-width": string, height}}
         */
        this.popup.popupInitStyle = {
          'min-width': options.minWidth + 'px',
          'min-height': options.minHeight + 'px',
          'max-width': options.maxWidth + 'px',
          'max-height': options.maxHeight + 'px',
          'height': options.height,
          'width': options.width > 0 ? options.width + 'px' : 'auto'
        };
      };

      Popup.prototype.close = function() {
        this.popup.removeEvents();
        $('#' + this.popup.iddiv).remove();
      };

      Popup.prototype.destroy = function() {
        this.popup.removeEvents();
        $('#' + this.popup.iddiv).remove();
      };

      return {
        open: function(options) {
          return new Popup(options);
        },
      };
    };
    this.$get.$inject = [
      '$compile',
      '$http',
      '$rootScope',
      '$timeout',
      'dialogsCommon',
      '$window'
    ];
  };
  return gcPopup;
});
