import treeService from "./tree.js";
import protectedSessionHolder from "./protected_session_holder.js";
import server from "./server.js";
import bundleService from "./bundle.js";
import Attributes from "./attributes.js";
import utils from "./utils.js";
import optionsService from "./options.js";
import appContext from "./app_context.js";
let showSidebarInNewTab = true;
optionsService.addLoadListener(options => {
    showSidebarInNewTab = options.is('showSidebarInNewTab');
});
class TabContext {
    /**
     * @param {TabRowWidget} tabRow
     * @param {object} state
     */
    constructor(tabRow, state = {}) {
        this.tabRow = tabRow;
        this.tabId = state.tabId || utils.randomString(4);
        this.$tab = $(this.tabRow.addTab(this.tabId));
        this.initialized = false;
        this.state = state;
    }
    async initTabContent() {
        if (this.initialized) {
            return;
        }
        this.initialized = true;
        this.$tabContent = $("
"); // FIXME
        this.noteChangeDisabled = false;
        this.isNoteChanged = false;
        this.attributes = new Attributes(this);
    }
    async setNote(note, notePath) {
        /** @property {NoteFull} */
        this.note = note;
        this.notePath = notePath;
        this.tabRow.updateTab(this.$tab[0], {title: this.note.title});
        if (!this.initialized) {
            return;
        }
        if (utils.isDesktop()) {
            this.attributes.refreshAttributes();
        } else {
            // mobile usually doesn't need attributes so we just invalidate
            this.attributes.invalidateAttributes();
        }
        this.setupClasses();
        this.setCurrentNotePathToHash();
        this.noteChangeDisabled = true;
        try {
        } finally {
            this.noteChangeDisabled = false;
        }
        this.setTitleBar();
        this.cleanup(); // esp. on windows autocomplete is not getting closed automatically
        setTimeout(async () => {
            // we include the note into recent list only if the user stayed on the note at least 5 seconds
            if (notePath && notePath === this.notePath) {
                await server.post('recent-notes', {
                    noteId: this.note.noteId,
                    notePath: this.notePath
                });
            }
        }, 5000);
        bundleService.executeRelationBundles(this.note, 'runOnNoteView', this);
        // after loading new note make sure editor is scrolled to the top
        // FIXME
        //this.getComponent().scrollToTop();
        appContext.trigger('activeNoteChanged');
    }
    async show() {
        if (!this.initialized) {
            await this.initTabContent();
            if (this.note) {
                await this.setNote(this.note, this.notePath);
            }
            else {
                // FIXME
                await this.renderComponent(); // render empty page
            }
        }
        this.setCurrentNotePathToHash();
        this.setTitleBar();
    }
    async renderComponent(disableAutoBook = false) {
        // FIXME
    }
    setTitleBar() {
        if (!this.$tabContent.is(":visible")) {
            return;
        }
        document.title = "Trilium Notes";
        if (this.note) {
            // it helps navigating in history if note title is included in the title
            document.title += " - " + this.note.title;
        }
    }
    hide() {
        if (this.initialized) {
            this.$tabContent.hide();
        }
    }
    setCurrentNotePathToHash() {
        if (this.isActive()) {
            document.location.hash = (this.notePath || "") + "-" + this.tabId;
        }
    }
    isActive() {
        return this.$tab[0] === this.tabRow.activeTabEl;
    }
    setupClasses() {
        for (const clazz of Array.from(this.$tab[0].classList)) { // create copy to safely iterate over while removing classes
            if (clazz !== 'note-tab') {
                this.$tab.removeClass(clazz);
            }
        }
        for (const clazz of Array.from(this.$tabContent[0].classList)) { // create copy to safely iterate over while removing classes
            if (clazz !== 'note-tab-content') {
                this.$tabContent.removeClass(clazz);
            }
        }
        this.$tab.addClass(this.note.cssClass);
        this.$tab.addClass(utils.getNoteTypeClass(this.note.type));
        this.$tab.addClass(utils.getMimeTypeClass(this.note.mime));
        this.$tabContent.addClass(this.note.cssClass);
        this.$tabContent.addClass(utils.getNoteTypeClass(this.note.type));
        this.$tabContent.addClass(utils.getMimeTypeClass(this.note.mime));
        this.$tabContent.toggleClass("protected", this.note.isProtected);
    }
    getComponent() {
        // FIXME
    }
    getComponentType(disableAutoBook) {
    // FIXME
    }
    async activate() {
        await this.tabRow.activateTab(this.$tab[0]);
    }
    async saveNote() {
        return; // FIXME
        if (this.note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) {
            return;
        }
        this.note.title = this.$noteTitle.val();
        this.note.content = this.getComponent().getContent();
        // it's important to set the flag back to false immediatelly after retrieving title and content
        // otherwise we might overwrite another change (especially async code)
        this.isNoteChanged = false;
        treeService.setNoteTitle(this.note.noteId, this.note.title);
        const resp = await server.put('notes/' + this.note.noteId, this.note.dto);
        this.note.dateModified = resp.dateModified;
        this.note.utcDateModified = resp.utcDateModified;
        if (this.note.isProtected) {
            protectedSessionHolder.touchProtectedSession();
        }
        // FIXME trigger "noteSaved" event so that title indicator is triggered
        this.eventReceived('noteSaved');
        // run async
        bundleService.executeRelationBundles(this.note, 'runOnNoteChange', this);
    }
    async saveNoteIfChanged() {
        if (this.isNoteChanged) {
            await this.saveNote();
            appContext.refreshTabs(this.tabId, this.note.noteId);
        }
    }
    noteChanged() {
        if (this.noteChangeDisabled) {
            return;
        }
        this.isNoteChanged = true;
        // FIXME: trigger noteChanged event
        //this.$savedIndicator.fadeOut();
    }
    async remove() {
        if (this.$tabContent) {
            // sometimes there are orphan autocompletes after closing the tab
            this.cleanup();
            await this.saveNoteIfChanged();
            this.$tabContent.remove();
        }
    }
    cleanup() {
        if (this.$tabContent && utils.isDesktop()) {
            this.$tabContent.find('.aa-input').autocomplete('close');
            $('.note-tooltip').remove();
        }
    }
    eventReceived(name, data) {
        if (!this.initialized) {
            return;
        }
        this.attributes.eventReceived(name, data);
    }
    getTabState() {
        if (!this.notePath) {
            return null;
        }
        return {
            tabId: this.tabId,
            notePath: this.notePath,
            active: this.tabRow.activeTabEl === this.$tab[0]
        }
    }
    stateChanged() {
        appContext.openTabsChanged();
    }
}
export default TabContext;