/**
 * @typedef {import('../view').RoomsList} RoomsList
 * @typedef {import('@converse/headless').MUC} MUC
 */
import { html } from "lit";
import { _converse, api, u, constants } from "@converse/headless";
import 'plugins/muc-views/modals/add-muc.js';
import 'plugins/muc-views/modals/muc-list.js';
import { __ } from 'i18n';
import { getUnreadMsgsDisplay } from "shared/chat/utils";

import '../styles/roomsgroups.scss';

const { CLOSED } = constants;
const { isUniView } = u;

/** @param {MUC} room */
function isCurrentlyOpen (room) {
    return isUniView() && !room.get('hidden');
}

/** @param {MUC} room */
function tplUnreadIndicator (room) {
    return html`<span class="list-item-badge badge badge--muc msgs-indicator">${ getUnreadMsgsDisplay(room) }</span>`;
}

function tplActivityIndicator () {
    return html`<span class="list-item-badge badge badge--muc msgs-indicator"></span>`;
}

/**
 * @param {RoomsList} el
 * @param {MUC} room
 */
function tplRoomItem (el, room) {
    const i18n_leave_room = __('Leave this groupchat');
    const has_unread_msgs = room.get('num_unread_general') || room.get('has_activity');
    return html`
        <li class="list-item controlbox-padded available-chatroom d-flex flex-row ${ isCurrentlyOpen(room) ? 'open' : '' } ${ has_unread_msgs ? 'unread-msgs' : '' }"
            data-room-jid="${room.get('jid')}">

            <a class="list-item-link open-room available-room w-100"
                data-room-jid="${room.get('jid')}"
                data-room-name="${room.getDisplayName()}"
                title="${__('Click to open this groupchat')}"
                @click=${ev => el.openRoom(ev)}>
                <converse-avatar
                    .model=${room}
                    class="avatar avatar-muc"
                    name="${room.getDisplayName()}"
                    nonce=${room.vcard?.get('vcard_updated')}
                    height="30" width="30"></converse-avatar>
                <span>${ room.get('num_unread') ?
                            tplUnreadIndicator(room) :
                            (room.get('has_activity') ? tplActivityIndicator() : '') }
                    ${room.getDisplayName()}</span>
            </a>

            <a class="list-item-action close-room"
                tabindex="0"
                data-room-jid="${room.get('jid')}"
                data-room-name="${room.getDisplayName()}"
                title="${i18n_leave_room}"
                @click=${(ev) => el.closeRoom(ev)}>
                <converse-icon
                    class="fa fa-sign-out-alt"
                    size="1.2em"
                    color="${ isCurrentlyOpen(room) ? 'var(--foreground-color)' : '' }"></converse-icon>
            </a>
        </li>`;
}

/**
 * @param {RoomsList} el
 * @param {string} domain
 * @param {MUC[]} rooms
 */
function tplRoomDomainGroup (el, domain, rooms) {
    const i18n_title = __('Click to hide these rooms');
    const collapsed = el.model.get('collapsed_domains');
    const is_collapsed = collapsed.includes(domain);
    return html`
    <div class="muc-domain-group" data-domain="${domain}">
        <a href="#"
           class="list-toggle muc-domain-group-toggle controlbox-padded"
           title="${i18n_title}"
           @click=${ev => el.toggleDomainList(ev, domain)}>

            <converse-icon
                class="fa ${ is_collapsed ? 'fa-caret-right' : 'fa-caret-down' }"
                size="1em"
                color="var(--muc-color)"></converse-icon>
            ${domain}
        </a>
        <ul class="items-list muc-domain-group-rooms ${ is_collapsed ? 'collapsed' : '' }" data-domain="${domain}">
            ${ rooms.map(room => tplRoomItem(el, room)) }
        </ul>
    </div>`;
}

/**
 * @param {RoomsList} el
 * @param {MUC[]} rooms
 */
function tplRoomDomainGroupList (el, rooms) {
    // The rooms should stay sorted as they are iterated and added in order
    const grouped_rooms = new Map();
    for (const room of rooms) {
        const roomdomain = room.get('jid').split('@').at(-1).toLowerCase();
        if (grouped_rooms.has(roomdomain)) {
            grouped_rooms.get(roomdomain).push(room);
        } else {
            grouped_rooms.set(roomdomain, [room]);
        }
    }
    const sorted_domains = Array.from(grouped_rooms.keys());
    sorted_domains.sort();

    return sorted_domains.map(domain => tplRoomDomainGroup(el, domain, grouped_rooms.get(domain)))
}

/**
 * @param {RoomsList} el
 */
export default (el) => {
    const group_by_domain = api.settings.get('muc_grouped_by_domain');
    const rooms = el.getRoomsToShow();
    const i18n_desc_rooms = __('Click to toggle the list of open groupchats');
    const i18n_heading_chatrooms = __('Groupchats');
    const i18n_title_list_rooms = __('Query server');
    const i18n_title_new_room = __('Add groupchat');
    const i18n_show_bookmarks = __('Bookmarks');
    const is_closed = el.model.get('toggle_state') === CLOSED;

    const btns = [
        html`<a class="dropdown-item show-add-muc-modal" role="button"
                @click="${(ev) => api.modal.show('converse-add-muc-modal', { 'model': el.model }, ev)}"
                data-toggle="modal"
                data-target="#add-chatrooms-modal">
                    <converse-icon class="fa fa-plus" size="1em"></converse-icon>
                    ${i18n_title_new_room}
        </a>`,
        html`<a class="dropdown-item show-list-muc-modal" role="button"
                @click="${(ev) => api.modal.show('converse-muc-list-modal', { 'model': el.model }, ev)}"
                data-toggle="modal"
                data-target="#muc-list-modal">
                    <converse-icon class="fa fa-list-ul" size="1em"></converse-icon>
                    ${i18n_title_list_rooms}
        </a>`,
        html`<a class="dropdown-item show-bookmark-list-modal" role="button"
                @click="${(ev) => api.modal.show('converse-bookmark-list-modal', { 'model': el.model }, ev)}"
                data-toggle="modal">
                    <converse-icon class="fa fa-bookmark" size="1em"></converse-icon>
                    ${i18n_show_bookmarks}
        </a>`,
    ];

    return html`
        <div class="d-flex controlbox-padded">
            <span class="w-100 controlbox-heading controlbox-heading--groupchats">
                <a class="list-toggle open-rooms-toggle" role="heading" aria-level="3"
                   title="${i18n_desc_rooms}"
                   @click=${ev => el.toggleRoomsList(ev)}>

                    ${i18n_heading_chatrooms}

                    ${rooms.length ? html`<converse-icon
                        class="fa ${ is_closed ? 'fa-caret-right' : 'fa-caret-down' }"
                        size="1em"
                        color="var(--muc-color)"></converse-icon>` : '' }
                </a>
            </span>
            <converse-dropdown class="btn-group dropstart" .items=${btns}></converse-dropdown>
        </div>

        <div class="list-container list-container--openrooms ${ rooms.length ? '' : 'hidden' }">
            <ul class="items-list rooms-list open-rooms-list ${ is_closed ? 'collapsed' : '' }">
                ${ group_by_domain ?
                    tplRoomDomainGroupList(el, rooms) :
                    rooms.map(/** @param {MUC} room */(room) => tplRoomItem(el, room))
                }
            </ul>
        </div>`;
}
