/**
 * AdsProDialog - własny system dialogów (zamiennik jquery-confirm)
 * API kompatybilne z jquery-confirm: $.confirm(options), $.alert(options)
 */
(function( $ )
{
  'use strict';

  var dialogCounter = 0;
  var activeDialogs = [];

  function AdsProDialog( options )
  {
    this.id = ++dialogCounter;
    this.options = $.extend( {}, AdsProDialog.defaults, options );
    this.$el = null;
    this.$box = null;
    this.$content = null;
    this._closed = false;
    this._autoCloseTimer = null;
    this._init();
  }

  AdsProDialog.defaults = {
    title: '',
    content: '',
    type: '',
    theme: '',
    buttons: {},
    closeIcon: false,
    closeIconClass: 'fa-solid fa-xmark',
    columnClass: '',
    boxWidth: '',
    useBootstrap: true,
    draggable: false,
    autoClose: '',
    onContentReady: null,
    onClose: null,
    onOpen: null
  };

  AdsProDialog.prototype = {

    _init: function()
    {
      this._buildDOM();
      this._bindEvents();
      this._appendToBody();
      this._applyAutoClose();
      this._triggerContentReady();
      this._focusInitialElement();
      activeDialogs.push( this );
    },

    _buildDOM: function()
    {
      var o = this.options;
      var typeClass = o.type ? ' adspro-dialog-type-' + o.type : '';

      var sizeStyle = '';
      var sizeClass = '';
      if ( !o.useBootstrap && o.boxWidth )
      {
        sizeStyle = 'max-width:' + o.boxWidth + ';width:100%;';
      }
      else if ( o.columnClass )
      {
        sizeClass = ' ' + o.columnClass.replace( /col-md-offset-\d+/g, '' ).trim();
      }

      var html =
        '<div class="adspro-dialog" data-dialog-id="' + this.id + '">' +
          '<div class="adspro-dialog-bg"></div>' +
          '<div class="adspro-dialog-scrollpane">' +
            '<div class="adspro-dialog-center' + sizeClass + '">' +
              '<div class="adspro-dialog-box jconfirm-box' + typeClass + '" style="' + sizeStyle + '" tabindex="-1">' +
                this._buildCloseIcon( o ) +
                this._buildHeader( o ) +
                '<div class="adspro-dialog-content-pane">' +
                  '<div class="adspro-dialog-content">' + o.content + '</div>' +
                '</div>' +
                this._buildButtons( o ) +
                '<div class="adspro-dialog-loading" style="display:none;">' +
                  '<div class="adspro-dialog-spinner"></div>' +
                '</div>' +
              '</div>' +
            '</div>' +
          '</div>' +
        '</div>';

      this.$el = $( html );
      this.$box = this.$el.find( '.adspro-dialog-box' );
      this.$content = this.$el.find( '.adspro-dialog-content' );
    },

    _buildCloseIcon: function( o )
    {
      if ( !o.closeIcon ) return '';
      var iconClass = o.closeIconClass || 'fa-solid fa-xmark';
      return '<div class="adspro-dialog-close-icon"><i class="' + iconClass + '"></i></div>';
    },

    _buildHeader: function( o )
    {
      if ( !o.title ) return '';
      return '<div class="adspro-dialog-title-c">' +
                '<span class="adspro-dialog-title">' + o.title + '</span>' +
             '</div>';
    },

    _buildButtons: function( o )
    {
      if ( !o.buttons || $.isEmptyObject( o.buttons ) ) return '';

      var html = '<div class="adspro-dialog-buttons">';
      var self = this;

      $.each( o.buttons, function( key, btnDef )
      {
        if ( typeof btnDef === 'function' )
        {
          btnDef = { action: btnDef };
          o.buttons[ key ] = btnDef;
        }

        var text = btnDef.text || key.charAt( 0 ).toUpperCase() + key.slice( 1 );
        var btnClass = btnDef.btnClass || 'btn-default';
        var isEnter = ( btnDef.keys && btnDef.keys.indexOf( 'enter' ) !== -1 );

        html += '<button type="button" class="adspro-dialog-btn btn ' + btnClass + '"' +
                ' data-btn-key="' + key + '"' +
                ( isEnter ? ' data-enter-key="true"' : '' ) +
                '>' + text + '</button>';
      });

      html += '</div>';
      return html;
    },

    _bindEvents: function()
    {
      var self = this;
      var o = this.options;

      // Backdrop click
      this.$el.find( '.adspro-dialog-bg' ).on( 'click', function()
      {
        self.close();
      });

      // Close icon
      this.$el.find( '.adspro-dialog-close-icon' ).on( 'click', function()
      {
        self.close();
      });

      // Buttons
      this.$el.find( '.adspro-dialog-btn' ).each( function()
      {
        var $btn = $( this );
        var key = $btn.data( 'btn-key' );
        var btnDef = o.buttons[ key ];

        // Referencje do buttonów (kompatybilność z $$formSubmit itp.)
        self[ '$$' + key ] = $btn;

        $btn.on( 'click', function()
        {
          if ( typeof btnDef === 'function' )
          {
            btnDef.call( self );
            self.close();
            return;
          }
          if ( btnDef && typeof btnDef.action === 'function' )
          {
            var result = btnDef.action.call( self );
            if ( result !== false )
            {
              self.close();
            }
          }
          else
          {
            self.close();
          }
        });
      });

      // Keyboard
      $( document ).on( 'keydown.adspro-dialog-' + this.id, function( e )
      {
        if ( self._closed ) return;
        if ( activeDialogs[ activeDialogs.length - 1 ] !== self ) return;

        if ( e.key === 'Escape' )
        {
          e.preventDefault();
          self.close();
        }
        if ( e.key === 'Enter' )
        {
          if ( $( e.target ).is( '.adspro-dialog-btn, textarea, select, input' ) ) return;
          var $enterBtn = self.$el.find( '.adspro-dialog-btn[data-enter-key="true"]' );
          if ( $enterBtn.length )
          {
            e.preventDefault();
            $enterBtn.trigger( 'click' );
          }
        }
      });

      // Draggable
      if ( o.draggable && $.fn.draggable )
      {
        this.$box.draggable({
          handle: '.adspro-dialog-title-c',
          cursor: 'move'
        });
        this.$el.find( '.adspro-dialog-title-c' ).css( 'cursor', 'move' );
      }
    },

    _appendToBody: function()
    {
      var baseZIndex = 99000 + ( this.id * 10 );
      this.$el.css( 'z-index', baseZIndex );
      $( 'body' ).append( this.$el );

      var self = this;
      requestAnimationFrame( function()
      {
        self.$el.addClass( 'adspro-dialog-open' );
      });

      if ( typeof this.options.onOpen === 'function' )
      {
        this.options.onOpen.call( this );
      }
    },

    _applyAutoClose: function()
    {
      var ac = this.options.autoClose;
      if ( !ac ) return;

      var parts = ac.split( '|' );
      if ( parts.length !== 2 ) return;

      var ms = parseInt( parts[ 1 ], 10 );
      var self = this;
      this._autoCloseTimer = setTimeout( function()
      {
        if ( !self._closed ) self.close();
      }, ms );
    },

    _triggerContentReady: function()
    {
      if ( typeof this.options.onContentReady === 'function' )
      {
        this.options.onContentReady.call( this );
      }
    },

    _focusInitialElement: function()
    {
      var self = this;

      setTimeout( function()
      {
        if ( self._closed ) return;
        if ( $( document.activeElement ).closest( self.$el ).length ) return;

        var $focusTarget = self.$el.find( '[autofocus]:visible:not(:disabled):first' );
        if ( !$focusTarget.length )
        {
          $focusTarget = self.$el.find( '.adspro-dialog-content input:visible:not(:disabled):first, .adspro-dialog-content select:visible:not(:disabled):first, .adspro-dialog-content textarea:visible:not(:disabled):first' ).first();
        }
        if ( !$focusTarget.length )
        {
          $focusTarget = self.$el.find( '.adspro-dialog-btn[data-enter-key="true"]:visible:not(:disabled):first' );
        }
        if ( !$focusTarget.length )
        {
          $focusTarget = self.$el.find( '.adspro-dialog-btn:visible:not(:disabled):first' );
        }
        if ( !$focusTarget.length )
        {
          $focusTarget = self.$box;
        }

        if ( $focusTarget.length )
        {
          $focusTarget.trigger( 'focus' );
        }
      }, 20 );
    },

    // --- Metody publiczne ---

    close: function()
    {
      if ( this._closed ) return;
      this._closed = true;

      if ( this._autoCloseTimer ) clearTimeout( this._autoCloseTimer );
      $( document ).off( 'keydown.adspro-dialog-' + this.id );

      var self = this;
      this.$el.removeClass( 'adspro-dialog-open' );
      this.$el.addClass( 'adspro-dialog-closing' );

      setTimeout( function()
      {
        self.$el.remove();
        var idx = activeDialogs.indexOf( self );
        if ( idx > -1 ) activeDialogs.splice( idx, 1 );
        if ( typeof self.options.onClose === 'function' )
        {
          self.options.onClose.call( self );
        }
      }, 250 );
    },

    showLoading: function( showContent )
    {
      this.$el.find( '.adspro-dialog-loading' ).show();
      if ( !showContent )
      {
        this.$el.find( '.adspro-dialog-content-pane' ).css( 'opacity', '0.3' );
      }
      this.$el.find( '.adspro-dialog-buttons' ).css({
        'pointer-events': 'none',
        'opacity': '0.5'
      });
    },

    hideLoading: function()
    {
      this.$el.find( '.adspro-dialog-loading' ).hide();
      this.$el.find( '.adspro-dialog-content-pane' ).css( 'opacity', '' );
      this.$el.find( '.adspro-dialog-buttons' ).css({
        'pointer-events': '',
        'opacity': ''
      });
    },

    setContent: function( html )
    {
      this.$content.html( html );
    },

    setTitle: function( title )
    {
      this.$el.find( '.adspro-dialog-title' ).html( title );
    }
  };

  // --- Rejestracja globalna ---

  $.confirm = function( options )
  {
    return new AdsProDialog( options );
  };

  $.alert = function( options )
  {
    if ( typeof options === 'string' )
    {
      options = {
        title: '',
        content: options,
        buttons: { ok: { text: 'OK', btnClass: 'btn-blue' } }
      };
    }

    if ( !options.buttons )
    {
      options.buttons = { ok: { text: 'OK', btnClass: 'btn-blue' } };
    }

    return new AdsProDialog( options );
  };

  $.dialog = function( options )
  {
    options = options || {};
    options.closeIcon = true;
    if ( !options.buttons )
    {
      options.buttons = {};
    }
    return new AdsProDialog( options );
  };

})( jQuery );
