<script type="text/javascript">
  function isMobile() {
    return window.matchMedia("only screen and (max-width: 799px)").matches;
  }

  function load_next_page(last_id, refresh_html=false) {
    if (refresh_html) {
      window.lock = true;
      $('#chat-log').html('');
      $('#loader').show();
    }
    var param = {
      'last_id': last_id,
      'only_messages': true,
    }
    $.get("{{ url('chat', '') }}" + window.room_id, param)
      .fail(function() {
      console.log("Fail to load page, last_id = " + last_id);
      window.lock = false;
    })
      .done(function(data) {
      if (refresh_html) {
        $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight);
      }
      var time = refresh_html ? 0 : 200;

      setTimeout(function() {
        $(".has_next").remove();
        let $chat_box = $('#chat-box');
        let lastMsgPos = scrollTopOfBottom($chat_box)

        $('#loader').hide();

        if (refresh_html) {
          $('#chat-log').append(data);
        }
        else {
          $('#chat-log').prepend(data);
        }

        postProcessMessages();

        if (!refresh_html) {
          $chat_box.scrollTop(scrollTopOfBottom($chat_box) - lastMsgPos);
        }
        else {
          $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight);
        }
        window.lock = false;
        window.has_next = parseInt($(".has_next").attr("value"));
      }, time);
    })
  }

  function postProcessMessages() {
    register_time($('.time-with-rel'));
    renderKatex();
    populateCopyButton();
    merge_authors();
  }

  function scrollTopOfBottom(container) {
    return container[0].scrollHeight - container.innerHeight()
  }

  function scrollContainer(container, loader) {
    container.scroll(function() {
      if (container.scrollTop() == 0) {
        if (!window.lock && window.has_next) {
          loader.show();
          var message_ids = $('.message').map(function() {
            return parseInt($(this).attr('message-id'));
          }).get();
          load_next_page(Math.min(...message_ids));
        }
      }
    })}

  function refresh_status(refresh_chat_info=false) {
    $.get("{{url('online_status_ajax')}}")
      .fail(function() {
      console.log("Fail to get online status");
    })
      .done(function(data) {
      if (data.status == 403) {
        console.log("Fail to retrieve data");
      }
      else {
        $('#chat-online-list').html(data).find('.toggle').each(function () {
          register_toggle($(this));
        });
        register_click_space();
        register_setting(false);
        color_selected_room();
      }
    })

    var data = {
      'user': window.other_user_id,
    };

    if (refresh_chat_info) {
      $('#chat-info').html('');
    }

    $.get("{{url('user_online_status_ajax')}}", data)
      .fail(function() {
      console.log("Fail to get user online status");
    })
      .done(function(data) {
      $('#chat-info').html(data);
      register_time($('.time-with-rel'));
      register_setting(true);
    })
  }

  function add_message(data) {
    var $data = $(data);

    $('#chat-log').append($data);
    $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight);
    postProcessMessages();
  }

  function add_new_message(message, room, is_self_author) {
    function callback(update) {
      if (!document['hidden']) {
        if (update) update_last_seen();
        refresh_status();
      }
      else if (!is_self_author) {
        window.unread_message++;
        document.title = "(" + window.unread_message + ") " + "{{ _('New message(s)') }}";
      }
    }

    if (room == window.room_id) {
      $.get({
        url: "{{ url('chat_message_ajax') }}",
        data: {
          message: message,
        },
        success: function (data) {
          add_message(data);
          callback(true);
        },
        error: function (data) {
          console.log('Could not add new message');
        }
      });
    }
    else {
      callback(false);
    }
  }

  function check_new_message(message, tmp_id, room) {
    if (room == room_id) {
      $.get({
        url: "{{ url('chat_message_ajax') }}",
        data: {
          message: message,
        },
        success: function (data) {
          var $body_block = $(data).find('.body-block');
          if ($('#message-'+tmp_id).length) {
            $('#message-'+tmp_id).replaceWith(data);
          }
          else if ($('#body-block-'+tmp_id).length) {
            $('#body-block-'+tmp_id).replaceWith($body_block);
          }
          else {
            add_new_message(message, room, true);
          }
          remove_unread_current_user();
          postProcessMessages();
        },
        error: function (data) {
          console.log('Fail to check message');
          var $body = $('#body-block-'+tmp_id + ' p');
          $body.css('text-decoration', 'line-through');
          $body.css('text-decoration-color', 'red');
        }
      });
    }
  }

  function merge_authors() {
    var time_limit = 5; // minutes
    var last = {
      username: null,
      time: null,
      $content: null
    };
    $('.body-message').each(function() {
      var username = $(this).find(".username a").text().trim();
      var $body = $(this).find(".content-message .body-block");
      var time = moment($(this).find(".time-with-rel").attr('data-iso'));
      var $content = $(this).children('.content-message');

      if (username == window.user.name) {
        $(this).find('.message-text').each(function() {
          $(this).removeClass('message-text-other').addClass('message-text-myself');
        });
      }

      if (username == last.username && time.diff(last.time, 'minutes') <= time_limit) {
        last.$content.append($body);
        $(this).parent().remove();
      }
      else {
        last.username = username;
        last.time = time;
        last.$content = $content;
      }
    });
  }

  function add_message_from_template(body, tmp_id) {
    if (window.room_id) {
      $("#last_msg-" + window.room_id).html(body);
    }
    var html = message_template();
    html = html.replaceAll('$body', body).replaceAll('$id', tmp_id);
    var $html = $(html);
    $html.find('.time-with-rel').attr('data-iso', (new Date()).toISOString());
    add_message($html[0].outerHTML);
  }

  function submit_chat() {
    {% if last_msg and not request.profile.mute %}
      if ($("#chat-input").val().trim()) {
        $('#chat-input-container').height('auto');
        var body = $('#chat-input').val().trim();

        var message = {
          body: body,
          room: window.room_id,
          tmp_id: Date.now(),
        };

        $('#chat-input').val('');
        $('#chat-input').css('height', '70%');

        add_message_from_template(body, message.tmp_id);

        $.post("{{ url('post_chat_message') }}", message)
          .fail(function(res) {
          console.log('Fail to send message');
          var $body = $('#message-text-'+ message.tmp_id);
          $body.css('text-decoration', 'line-through');
          $body.css('background', 'red');
        })
          .done(function(res, status) {
          $('#empty_msg').hide();
          $('#chat-input').focus();
        })
      }
    {% endif %}
  }

  function resize_emoji(element) {
    var html = element.html();
    html = html.replace(/(\p{Extended_Pictographic})/ug, `<span class="big-emoji">$1</span>`);
    element.html(html);
  }

  function insert_char_after_cursor(elem, char) {
    var val = elem.value;
    if (typeof elem.selectionStart == "number" && typeof elem.selectionEnd == "number") {
      var start = elem.selectionStart;
      var prefix = elem.value.slice(0, start);
      var prefix_added = prefix + char;
      var chars = [...val];
      chars.splice([...prefix].length, 0, char);
      elem.value = chars.join('');
      elem.selectionStart = elem.selectionEnd = prefix_added.length;
    } else if (document.selection && document.selection.createRange) {
      var range = document.selection.createRange();
      elem.focus();
      range.text = char;
      range.collapse(false);
      range.select();
    }
  }

  function color_selected_room() {
    $(".status-row").removeClass("selected-status-row");
    $("#click_space_" + window.other_user_id).addClass("selected-status-row");
  }

  function show_right_panel() {
    if (isMobile()) {
      $('.chat-left-panel').hide();
      $('#chat-area').css('display', 'flex');
      $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight);
    }
  }

  function hide_right_panel() {
    if (isMobile()) {
      $('.chat-left-panel').show();
      $('#chat-area').hide();
    }
  }

  function load_room(encrypted_user) {
    if (window.lock_click_space) return;

    function callback() {
      history.replaceState(null, '', "{{url('chat', '')}}" + window.room_id);
      load_next_page(null, true);
      update_last_seen();
      refresh_status(true);

      show_right_panel();
      $('#chat-input').focus();
      $('#chat-input').val('').trigger('input');
    }
    window.lock_click_space = true;
    if (encrypted_user) {
      $.get("{{url('get_or_create_room')}}" + `?other=${encrypted_user}`)
        .done(function(data) {
        window.room_id = data.room;
        window.other_user_id = data.other_user_id;
        color_selected_room();
        callback();
        $('#chat-input').attr('maxlength', 5000);
      })
        .fail(function() {
        console.log('Fail to get_or_create_room');
      })
    }
    else {
      window.room_id = '';
      window.other_user_id = '';
      color_selected_room();
      callback();
      $('#chat-input').attr('maxlength', 200);
    }
    window.lock_click_space = false;
  }

  function register_click_space() {
    $('.click_space').on('click', function(e) {
      if ($(this).attr('id') == 'click_space_' + window.other_user_id) {
        show_right_panel();
        return;
      }
      var other_user = $(this).attr('value');
      load_room(other_user);
    });
    $('#lobby_row').on('click', function(e) {
      if (window.room_id) {
        load_room(null);
      }
      else {
        show_right_panel();
      }
    });
  }

  function update_last_seen() {
    var data = {
      room: window.room_id
    };

    $.post("{{ url('update_last_seen') }}", data)
      .fail(function(data) {
      console.log('Fail to update last seen');
    })
      .done(function(data) {

    })
  }

  function remove_unread_current_user() {
    if (window.other_user_id) {
      $("#unread-count-" + window.other_user_id).hide();
    }
    else {
      $('#unread-count-lobby').hide();
    }
  }

  function register_setting(is_on_user_status_bar) {
    let $setting_button = is_on_user_status_bar ? $('.user-setting-button') : $('.setting-button');
    $setting_button.on('click', function(e) {
      e.stopPropagation();
      $('.setting-content').not($(this).siblings('.setting-content')).hide();
      $(this).siblings('.setting-content').toggle();
    });
    $('.setting-content a').on('click', function(e) {
      e.stopPropagation();
      var href = $(this).attr('href');
      href += '?next=' + window.location.pathname;
      $(this).attr('href', href);
    })
    $(document).on('click', function() {
      $('.setting-content').hide();
    });
  }
  $(function() {
    $('#loader').hide();
    update_last_seen();
    merge_authors();
    window.has_next = parseInt($(".has_next").attr("value"));

    scrollContainer($('#chat-box'), $('#loader'))

    {% if request.user.is_staff %}
      $(document).on("click", ".chat_remove", function() {
        var elt = $(this);
        $.ajax({
          url: "{{ url('delete_chat_message') }}",
          type: 'post',
          data: {
            message: elt.attr('value'),
          },
          dataType: 'json',
          success: function(data){
            var $block = elt.parent();
            if ($block.parent().find('.body-block').length > 1) {
              $block.remove();
            }
            else {
              elt.closest('li').remove();
            }
          },
          fail: function(data) {
            console.log('Fail to delete');
          },
        });
      });
      $(document).on("click", ".chat_mute", function() {
        if (confirm("{{_('Mute this user and delete all messages?')}}")) {
          var elt = $(this);
          $.ajax({
            url: "{{ url('mute_chat_message') }}",
            type: 'post',
            data: {
              message: elt.attr('value'),
            },
            dataType: 'json',
            success: function(data){
              window.location.reload();
            },
            fail: function(data) {
              console.log('Fail to delete');
            },
          });
        }
      });
    {% endif %}

    $("#chat-log").show();
    $("#chat-log").change(function() {
      $('#chat-log').scrollTop($('#chat-log')[0].scrollHeight);
    });

    $('#chat-input').focus();

    $('#chat-input').keydown(function(e) {
      if (e.keyCode === 13) {
        if (e.ctrlKey || e.shiftKey) {
          insert_char_after_cursor(this, "\n");
        }
        else {
          e.preventDefault();
          submit_chat();
        }
        return false
      }
      return true
    });

    setInterval(refresh_status, 2 * 60 * 1000);

    $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight);

    const button = document.querySelector('#emoji-button');
    const tooltip = document.querySelector('.tooltip');
    const popper = Popper.createPopper(button, tooltip, {
      placement: isMobile() ? 'auto-end' : 'left',
    });

    function toggleEmoji() {
      tooltip.classList.toggle('shown');
      popper.update();
    }
    $('#emoji-button').on('click', function(e) {
      e.preventDefault();
      e.stopPropagation();
      toggleEmoji();
    });

    // Đóng bảng emoji khi click bất kỳ chỗ nào trên màn hình
    document.addEventListener("click", function(e) {
      if (!tooltip.contains(e.target)) {
        tooltip.classList.remove('shown'); // Ẩn bảng emoji
      }
    });

    $('emoji-picker').on('emoji-click', function(e) {
      var $chat = $('#chat-input').get(0);
      insert_char_after_cursor($chat, e.detail.unicode);
      $chat.focus();
    })

    register_click_space();

    document.addEventListener('keydown', function(e) {
      if (e.keyCode === 27 && $('.tooltip').hasClass('shown')) {
        toggleEmoji();
      }
    })

    $('#search-handle').replaceWith($('<select>').attr({
      id: 'search-handle',
      name: 'other',
      onchange: 'form.submit()'
    }));

    var in_user_redirect = false;
    $('#search-handle').select2({
      placeholder: '<i class="fa fa-search"></i> {{ _('Search by handle...') }}',
      ajax: {
        url: '{{ url('chat_user_search_select2_ajax') }}',
        delay: 250,
        cache: true,
      },
      minimumInputLength: 1,
      escapeMarkup: function (markup) {
        return markup;
      },
      templateResult: function (data, container) {
        return $('<span>')
          .append($('<img>', {
          'class': 'user-search-image', src: data.gravatar_url,
          width: 24, height: 24
        }))
          .append($('<span>', {'class': data.display_rank + ' user-search-name'}).text(data.text))
          .append($('<a>', {href: '/user/' + data.text, 'class': 'user-redirect'})
            .append($('<i>', {'class': 'fa fa-mail-forward'}))
            .mouseover(function () {
            in_user_redirect = true;
          }).mouseout(function () {
            in_user_redirect = false;
          }));
      }
    }).on('select2:selecting', function () {
      return !in_user_redirect;
    });

    $("#chat-input").on("keyup", function() {
      $("#chat-input").scrollTop($("#chat-input")[0].scrollHeight);
    });

    // https://stackoverflow.com/questions/42121565/detecting-class-change-without-setinterval
    if (typeof(MutationObserver) !== undefined) {
      var observer = new MutationObserver(function (event) {
        if (!document['hidden'] && window.unread_message > 0) {
          update_last_seen();
          refresh_status();
          window.unread_message = 0;
          document.title = "{{_('Chat Box')}}";
        }
      })

      observer.observe(document.body, {
        attributes: true,
        attributeFilter: ['class'],
        childList: false,
        characterData: false
      })
    }
    register_setting(true);
    register_setting(false);
    color_selected_room();

    $('#chat-input').on('input', function() {
      if (this.scrollHeight > this.clientHeight) {
        this.style.height = (this.scrollHeight) + 'px';
        $(this).css('border-radius', '30px');
      } else {
        $(this).css('height', '70%');
      }
    });

    $('#submit-button').on('click', submit_chat);
    register_copy_clipboard($("#chat-input"), () => {
      $('#chat-input').trigger('input');
    });
  });
</script>