{#
 # ---------------------------------------------------------------------
 #
 # GLPI - Gestionnaire Libre de Parc Informatique
 #
 # http://glpi-project.org
 #
 # @copyright 2015-2025 Teclib' and contributors.
 # @licence   https://www.gnu.org/licenses/gpl-3.0.html
 #
 # ---------------------------------------------------------------------
 #
 # LICENSE
 #
 # This file is part of GLPI.
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #
 # ---------------------------------------------------------------------
 #}

{% set rand = random() %}

{% set load_actors = params['load_actors'] ?? true %}
{% set actors = load_actors ? item.getActorsForType(actortypeint, params) : [] %}

{% set required = false %}
{% if itiltemplate.isMandatoryField('_users_id_' ~ actortype) or itiltemplate.isMandatoryField('_groups_id_' ~ actortype) or (actortype == 'assign' and itiltemplate.isMandatoryField('_suppliers_id_' ~ actortype)) %}
   {% set required = true %}
{% endif %}

{% set is_actor_hidden = false %}
{% if itiltemplate.isHiddenField('_users_id_' ~ actortype) and itiltemplate.isHiddenField('_groups_id_' ~ actortype) and (actortype != 'assign' or itiltemplate.isHiddenField('_suppliers_id_' ~ actortype)) %}
   {% set is_actor_hidden = true %}
{% endif %}

{% set onchange = '' %}
{% set allow_auto_submit = allow_auto_submit ?? true %}
{% if allow_auto_submit and item.isNewItem() and actortype == "requester" %}
   {% set onchange = 'this.form.submit();' %}
{% endif %}

{% if not is_actor_hidden %}
   <select class="form-select" multiple="true" id="actor_{{ rand }}" data-actor-type="{{ actortype }}"
        {{ required ? 'required' : '' }}>
   {% for actor in actors %}
      {% set unique_id = "user_opt_" ~ actortype ~ actor.itemtype ~ actor.items_id %}
      <option selected="true" value="{{ actor['itemtype'] ~ '_' ~ actor['items_id'] }}"
            data-itemtype="{{ actor['itemtype'] }}" data-items-id="{{ actor['items_id'] }}"
            data-use-notification="{{ actor['use_notification'] }}"
            data-default-email="{{ actor['default_email'] ?? '' }}"
            data-alternative-email="{{ actor['alternative_email'] ?? '' }}"
            {% if (actor['itemtype'] == 'User' and itiltemplate.isHiddenField('_users_id_' ~ actortype)) or (actor['itemtype'] == 'Group' and itiltemplate.isHiddenField('_groups_id_' ~ actortype)) %}
               disabled="disabled" style="display: none;"
            {% endif %}
            data-text="{{ actor['text']|verbatim_value }}" data-title="{{ actor['title']|verbatim_value }}" data-glpi-popover-source="content{{ unique_id }}">
         {{ actor['title']|verbatim_value }}
      </option>
   {% endfor %}
   </select>

   {% if not item.isNewItem() and not params['template_preview'] and canassigntome %}
      {{ include('components/itilobject/actors/assign_to_me.html.twig') }}
   {% endif %}

   {#
      Prevent WAF (Web Application Firewall) from triggering on item.fields['content']

      The WAF rule (signature ID 010000092) is triggered due to the presence of HTML-encoded content
      in the 'content' field, which is falsely identified as a potential XSS injection.
      This key is removed from the AJAX payload to avoid false positives.

      Reference: https://github.com/glpi-project/glpi/pull/10300
   #}
   {% set safe_item_fields = item.fields|filter((value, key) => key != 'content') %}

   <script type="text/javascript">

   // Do not use jquery ready wrapper here as it behave unexpectedly with ajax
   // requests, adding an unnecessary delay
   (function() {
      var actorytype = '{{ actortype }}';

      // function to display an option in the list or the selected input
      var genericTemplate_{{ rand }} = function(option = {}, is_selection = false) {
         var element   = $(option.element);
         var itemtype  = element.data('itemtype') ?? option.itemtype;
         var items_id  = element.data('items-id') ?? option.items_id;
         var text      = escapeMarkupText(element.data('text') ?? option.text ?? '');
         var title     = escapeMarkupText(element.data('title') ?? option.title ?? '');
         var use_notif = element.data('use-notification') ?? option.use_notification ?? 1;
         var alt_email = element.data('alternative-email') ?? option.alternative_email ?? '';

         var icon = "";
         var fk   = "";
         switch (itemtype) {
            case "User":
               if (items_id == 0) {
                  text = alt_email;
                  icon = `<i class="ti  fa-fw ti-mail mx-1" title="{{ __('Direct email') }}"></i>`;
               } else {
                  icon = `<i class="ti  fa-fw ti-user mx-1" title="{{ 'User'|itemtype_name }}"></i>`;
               }
               if ("{{ actortype }}" == "assign") {
                  fk = "users_id_assign";
               } else if ("{{ actortype }}" == "requester") {
                  fk = "users_id_requester";
               } else if ("{{ actortype }}" == "observer") {
                  fk = "users_id_observer";
               }
               break;
            case "Group":
               icon = `<i class="ti  fa-fw ti-users mx-1" title="{{ 'Group'|itemtype_name }}"></i>`;
               if ("{{ actortype }}" == "assign") {
                  fk = "groups_id_assign";
               } else if ("{{ actortype }}" == "requester") {
                  fk = "groups_id_requester";
               } else if ("{{ actortype }}" == "observer") {
                  fk = "groups_id_observer";
               }
               break;
            case "Supplier":
               icon = `<i class="ti fa-fw ti-package mx-1" title="{{ 'Supplier'|itemtype_name }}"></i>`;
               fk   = "suppliers_id_assign";
               break;
         }

         var actions = "";
         {% if canupdate %}
         if (['User', 'Supplier', 'Email'].includes(itemtype)
            && is_selection) {
            var fa_class = "far";
            if (use_notif) {
               fa_class = "fas";
            }
            actions = `<button class="btn btn-sm btn-ghost-secondary edit-notify-user"
                              data-bs-toggle="tooltip" data-bs-placement="top"
                              title="{{ __('Email followup') }}"
                              type="button">
               <i class="${fa_class} fa-bell notify-icon"></i>
            </button>`;
         }
         {% endif %}

         // manage specific display for tree data (like groups)
         var indent = "";
         if (!is_selection && "level" in option && option.level > 1) {
            for (let index = 1; index < option.level; index++) {
               indent = "&nbsp;&nbsp;&nbsp;"+indent;
            }
            indent = indent+"&raquo;";
         }

         // prepare html for option element
         var text = (is_selection && itemtype == "Group") ? title : text;
         var option_text    = `<span class="actor_text">${text}</span>`;
         var option_element = $(`<span class="actor_entry" data-itemtype="${itemtype}" data-items-id="${items_id}" data-actortype="${actorytype}">${indent}${icon}${option_text}${actions}</span>`);

          if (is_selection && itemtype == "User") {
              const unique_id = "user_opt_" + actor_select.attr('data-actor-type') + "User" + items_id;
              $.ajax({
                  url: '{{ path('/ajax/comments.php') }}',
                  type: 'POST',
                  data: {
                      'itemtype': 'User',
                      'value': items_id,
                  }
              }).then((result) => {
                  if (result) {
                      actor_select.parent().append('<' + `div id="content${unique_id}" style="display: none;">` + result + '<' + '/div>');
                      option_element.attr('data-glpi-popover-source', `content${unique_id}`);
                  }
              });
          }

         if (is_selection && itemtype == "Group") {
            const unique_id = "group_opt_" + actor_select.attr('data-actor-type') + "Group" + items_id;
            $.ajax({
               url: '{{ path('/ajax/comments.php') }}',
               type: 'POST',
               data: {
                  'itemtype': 'Group',
                  'value': items_id,
               }
            }).then((result) => {
               if (result) {
                  actor_select.parent().append('<' + `div id="content${unique_id}" style="display: none;">` + result + '<' + '/div>');
                  option_element.attr('data-glpi-popover-source', `content${unique_id}`);
               }
            });
         }

         if (is_selection && itemtype == "Supplier") {
            const unique_id = "supplier_opt_" + actor_select.attr('data-actor-type') + "Supplier" + items_id;
            $.ajax({
               url: '{{ path('/ajax/comments.php') }}',
               type: 'POST',
               data: {
                  'itemtype': 'Supplier',
                  'value': items_id,
               }
            }).then((result) => {
               if (result) {
                  actor_select.parent().append('<' + `div id="content${unique_id}" style="display: none;">` + result + '<' + '/div>');
                  option_element.attr('data-glpi-popover-source', `content${unique_id}`);
               }
            });
         }

         // manage ticket information (number of assigned ticket for an actor)
         if (is_selection && itemtype != "Email") {
            var label = '';
            if ("{{ actortype }}" == "assign") {
               label = "{{ __('Number of tickets already assigned') }}";
            } else if ("{{ actortype }}" == "requester") {
               label = "{{ __('Number of tickets as requester') }}";
            }
            var existing_element = $(
               `<span class="assign_infos ms-1" title="${label}"
                     data-bs-toggle="tooltip" data-bs-placement="top"
                     data-id="${items_id}" data-fk="${fk}">
                  <i class="fas fa-spinner fa-spin"></i>
               </span>`
            );
            option_element.append(existing_element);

            $.get("{{ path('/ajax/actorinformation.php') }}", {
               [fk]: items_id,
               only_number: true,
            }).done(function (number) {
               var badge = "";
               if (number.length > 0) {
                  badge = `<span class="badge bg-secondary-lt">
                  ${number}
               </span>`;
               }
               existing_element.html(badge);
            });
         }

         return option_element;
      };

      var select2_width = "{{ canassigntome ? 'calc(100% - 30px)' : '100%' }}";

      const actor_select = $("#actor_{{ rand }}");
      actor_select.select2({
         tags: true,
         width: select2_width,
         tokenSeparators: [',', ' '],
         containerCssClass: 'actor-field',
         templateSelection: function(option) { return genericTemplate_{{ rand }}(option, true); },
         templateResult:    function(option) { return genericTemplate_{{ rand }}(option, false); },
         disabled: {{ canupdate ? 'false' : 'true' }},
         createTag: function (params) {
            var term = $.trim(params.term);

            if (term === '') {
               return null;
            }

            // Don't offset to create a tag if it's not an email
            if (!new RegExp(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,63}$/).test(term)) {
               // Return null to disable tag creation
               return null;
            }

            return {
               id: term,
               text: term,
               itemtype: "User",
               items_id: 0,
               use_notification: 1,
               alternative_email: term,
            }
         },
         ajax: {
            url: '{{ path('/ajax/actors.php') }}',
            datatype: 'json',
            type: 'POST',
            delay:250,
            data: function (params) {
               var is_new_item = {{ item.isNewItem() ? "true" : "false" }};
               return {
                  action: 'getActors',
                  actortype: actorytype,
                  users_right: '{{ users_right ?? 'all' }}',
                  entity_restrict: (actors.requester.length == 0 && is_new_item) ? -1 : {{ entities_id }},
                  searchText: params.term,
                  _idor_token: '{{ idor_token(item.getType(), {'users_right': users_right ?? 'all'}) }}',
                  itiltemplate_class: '{{ itiltemplate.getType() }}',
                  itiltemplates_id: {{ itiltemplate.fields['id'] ?? 0 }},
                  itemtype: '{{ item.getType() }}',
                  items_id: {{ item.isNewItem() ? -1 : item.fields['id'] }},
                  item: {{ safe_item_fields|json_encode|raw }},
                  returned_itemtypes: {{ (returned_itemtypes ?? ['User', 'Group', 'Supplier'])|json_encode()|raw }},
                  page: params.page || 1
               };
            },
         }
      }).on('select2:open', () => {
          // Close popovers
          $('.popover').popover('hide');
      });

      $(function () {
         actor_select.parent().popover({
            selector: '[data-glpi-popover-source]',
            container: actor_select.parent(),
            html: true,
            sanitize: false,
            trigger: 'hover',
            delay: {
               hide: 300
            },
            template: '<' + 'div class="popover shadow" role="tooltip"><' + 'div class="popover-arrow"><' + '/div><' + 'h3 class="popover-header"><' + '/h3><' + 'div class="popover-body"><' + '/div><' + '/div>',
            content: function() {
               // Close other popovers
               $('.popover').popover('hide');
               return $('#' + $(this).attr('data-glpi-popover-source')).html();
            }
         }).on('hide.bs.popover', function () {
            // prevent closing popover when user card is hover
            if ($('.user-info-card:hover').length > 0) {
               return false;
            }
            // prevent closing popover when group card is hover
            if ($('.group-info-card:hover').length > 0) {
               return false;
            }
            // prevent closing popover when supplier card is hover
            if ($('.supplier-info-card:hover').length > 0) {
               return false;
            }
         });
      });

        // when the mouse leave the user card in the popover, close it
        $(document).on('mouseleave', '.user-info-card', function() {
            setTimeout(() => {
                $('.popover').popover('hide');
            }, 300);
        });

        // when the mouse leave the group card in the popover, close it
        $(document).on('mouseleave', '.group-info-card', function() {
            setTimeout(() => {
                $('.popover').popover('hide');
            }, 300);
        });

      // manage actors change
      var updateActors{{ rand }} = function() {
         var data = $("#actor_{{ rand }}").select2('data');

         var new_actors = [];
         data.forEach(function(selection) {
            var element = $(selection.element);

            var itemtype  = selection.itemtype ?? element.data('itemtype');
            var items_id  = selection.items_id ?? element.data('items-id');
            var use_notif = selection.use_notification  ?? element.data('use-notification')  ?? false;
            var def_email = selection.default_email ?? element.data('default-email') ?? '';
            var alt_email = selection.alternative_email ?? element.data('alternative-email') ?? '';

            if (itemtype == "Email") {
               itemtype  = "User";
               use_notif = true;
               alt_email = selection.id;
            }

            new_actors.push({
               itemtype: itemtype,
               items_id: items_id,
               use_notification: use_notif,
               default_email: def_email,
               alternative_email: alt_email,
            });
         });

         actors[actorytype] = new_actors;

         saveActorsToDom();
      };
      $("#actor_{{ rand }}").on('select2:select', function () {
         updateActors{{ rand }}();
         {{ onchange }}
      });
      $("#actor_{{ rand }}").on('select2:unselect', function () {
         updateActors{{ rand }}();
         {{ onchange }}
      });

      // intercept event for edit notification button
      document.addEventListener('click', event => {
         if (event.target.closest("#actor_{{ rand }} + .select2 .edit-notify-user")) {
            return openNotifyModal(event);
         }
         // if a click on assign info is detected prevent opening of select2
         if (event.target.closest("#actor_{{ rand }} + .select2 .assign_infos")) {
            event.stopPropagation();
         }
      }, {capture: true})
      document.addEventListener('keydown', event => {
         if (event.target.closest("#actor_{{ rand }} + .select2 .edit-notify-user")
            && event.key == "Enter") {
            return openNotifyModal(event);
         }
      }, {capture: true})

      {% if itiltemplate.isHiddenField('_users_id_' ~ actortype) %}
         $(".actor_entry[data-itemtype=\"User\"][data-actortype=\"{{ actortype }}\"]").parent().css("display", "none");
      {% endif %}
      {% if itiltemplate.isHiddenField('_groups_id_' ~ actortype) %}
         $(".actor_entry[data-itemtype=\"Group\"][data-actortype=\"{{ actortype }}\"]").parent().css("display", "none");
      {% endif %}
   })();
   </script>
{% endif %}
