"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Folder_1 = require("@joplin/lib/models/Folder");
const Tag_1 = require("@joplin/lib/models/Tag");
const BaseModel_1 = require("@joplin/lib/BaseModel");
const Setting_1 = require("@joplin/lib/models/Setting");
const locale_1 = require("@joplin/lib/locale");
const trash_1 = require("@joplin/lib/services/trash");
const ListWidget = require('tkwidgets/ListWidget.js');
class FolderListWidget extends ListWidget {
    constructor() {
        super();
        this.folders_ = [];
        this.tags_ = [];
        this.searches_ = [];
        this.selectedFolderId_ = null;
        this.selectedTagId_ = null;
        this.selectedSearchId_ = null;
        this.notesParentType_ = 'Folder';
        this.updateIndexFromSelectedFolderId_ = false;
        this.updateItems_ = false;
        this.trimItemTitle = false;
        this.showIds = false;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
        this.itemRenderer = (item) => {
            const output = [];
            if (item === '-') {
                output.push('-'.repeat(this.innerWidth));
            }
            else if (item.type_ === Folder_1.default.modelType()) {
                const depth = this.folderDepth(this.folders, item.id);
                output.push(' '.repeat(depth));
                // Add collapse/expand indicator
                const hasChildren = this.folderHasChildren_(this.folders, item.id);
                if (hasChildren) {
                    const collapsedFolders = Setting_1.default.value('collapsedFolderIds');
                    const isCollapsed = collapsedFolders.includes(item.id);
                    output.push(isCollapsed ? '[+] ' : '[-] ');
                }
                else {
                    output.push('  '); // Space for alignment
                }
                if (this.showIds) {
                    output.push(Folder_1.default.shortId(item.id));
                }
                output.push(Folder_1.default.displayTitle(item));
                if (Setting_1.default.value('showNoteCounts') && !item.deleted_time && item.id !== (0, trash_1.getTrashFolderId)()) {
                    let noteCount = item.note_count;
                    if (this.folderHasChildren_(this.folders, item.id)) {
                        for (let i = 0; i < this.folders.length; i++) {
                            if (this.folders[i].parent_id === item.id) {
                                // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
                                noteCount -= this.folders[i].note_count;
                            }
                        }
                    }
                    output.push(noteCount);
                }
            }
            else if (item.type_ === Tag_1.default.modelType()) {
                output.push(`[${Folder_1.default.displayTitle(item)}]`);
            }
            else if (item.type_ === BaseModel_1.default.TYPE_SEARCH) {
                output.push((0, locale_1._)('Search:'));
                output.push(item.title);
            }
            return output.join(' ');
        };
    }
    folderDepth(folders, folderId) {
        let output = 0;
        while (true) {
            const folder = BaseModel_1.default.byId(folders, folderId);
            const folderParentId = (0, trash_1.getDisplayParentId)(folder, folders.find((f) => f.id === folder.parent_id));
            if (!folder || !folderParentId)
                return output;
            output++;
            folderId = folderParentId;
        }
    }
    get selectedFolderId() {
        return this.selectedFolderId_;
    }
    set selectedFolderId(v) {
        this.selectedFolderId_ = v;
        this.updateIndexFromSelectedItemId();
        this.invalidate();
    }
    get selectedSearchId() {
        return this.selectedSearchId_;
    }
    set selectedSearchId(v) {
        this.selectedSearchId_ = v;
        this.updateIndexFromSelectedItemId();
        this.invalidate();
    }
    get selectedTagId() {
        return this.selectedTagId_;
    }
    set selectedTagId(v) {
        this.selectedTagId_ = v;
        this.updateIndexFromSelectedItemId();
        this.invalidate();
    }
    get notesParentType() {
        return this.notesParentType_;
    }
    set notesParentType(v) {
        this.notesParentType_ = v;
        this.updateIndexFromSelectedItemId();
        this.invalidate();
    }
    get searches() {
        return this.searches_;
    }
    set searches(v) {
        this.searches_ = v;
        this.updateItems_ = true;
        this.updateIndexFromSelectedItemId();
        this.invalidate();
    }
    get tags() {
        return this.tags_;
    }
    set tags(v) {
        this.tags_ = v;
        this.updateItems_ = true;
        this.updateIndexFromSelectedItemId();
        this.invalidate();
    }
    get folders() {
        return this.folders_;
    }
    set folders(v) {
        this.folders_ = v;
        this.updateItems_ = true;
        this.updateIndexFromSelectedItemId();
        this.invalidate();
    }
    toggleShowIds() {
        this.showIds = !this.showIds;
        this.invalidate();
    }
    folderHasChildren_(folders, folderId) {
        for (let i = 0; i < folders.length; i++) {
            const folder = folders[i];
            const folderParentId = (0, trash_1.getDisplayParentId)(folder, folders.find((f) => f.id === folder.parent_id));
            if (folderParentId === folderId)
                return true;
        }
        return false;
    }
    render() {
        if (this.updateItems_) {
            this.logger().debug('Rebuilding items...', this.notesParentType, this.selectedJoplinItemId, this.selectedSearchId);
            const wasSelectedItemId = this.selectedJoplinItemId;
            const previousParentType = this.notesParentType;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
            let newItems = [];
            const orderFolders = (parentId) => {
                for (let i = 0; i < this.folders.length; i++) {
                    const f = this.folders[i];
                    const originalParent = this.folders_.find((f) => f.id === f.parent_id);
                    const folderParentId = (0, trash_1.getDisplayParentId)(f, originalParent); // f.parent_id ? f.parent_id : '';
                    if (folderParentId === parentId) {
                        newItems.push(f);
                        // Only recurse into children if the folder is not collapsed
                        if (this.folderHasChildren_(this.folders, f.id)) {
                            const collapsedFolders = Setting_1.default.value('collapsedFolderIds');
                            if (!collapsedFolders.includes(f.id)) {
                                orderFolders(f.id);
                            }
                        }
                    }
                }
            };
            orderFolders('');
            if (this.tags.length) {
                if (newItems.length)
                    newItems.push('-');
                newItems = newItems.concat(this.tags);
            }
            if (this.searches.length) {
                if (newItems.length)
                    newItems.push('-');
                newItems = newItems.concat(this.searches);
            }
            this.items = newItems;
            this.notesParentType = previousParentType;
            this.updateIndexFromSelectedItemId(wasSelectedItemId);
            this.updateItems_ = false;
        }
        super.render();
    }
    get selectedJoplinItemId() {
        if (!this.notesParentType)
            return '';
        if (this.notesParentType === 'Folder')
            return this.selectedFolderId;
        if (this.notesParentType === 'Tag')
            return this.selectedTagId;
        if (this.notesParentType === 'Search')
            return this.selectedSearchId;
        throw new Error(`Unknown parent type: ${this.notesParentType}`);
    }
    get selectedJoplinItem() {
        const id = this.selectedJoplinItemId;
        const index = this.itemIndexByKey('id', id);
        return this.itemAt(index);
    }
    updateIndexFromSelectedItemId(itemId = null) {
        if (itemId === null)
            itemId = this.selectedJoplinItemId;
        const index = this.itemIndexByKey('id', itemId);
        this.currentIndex = index >= 0 ? index : 0;
    }
    toggleFolderCollapse() {
        const item = this.currentItem;
        if (item && item.type_ === Folder_1.default.modelType() && this.folderHasChildren_(this.folders, item.id)) {
            const collapsedFolders = Setting_1.default.value('collapsedFolderIds');
            const isCollapsed = collapsedFolders.includes(item.id);
            if (isCollapsed) {
                const newCollapsed = collapsedFolders.filter((id) => id !== item.id);
                Setting_1.default.setValue('collapsedFolderIds', newCollapsed);
            }
            else {
                Setting_1.default.setValue('collapsedFolderIds', [...collapsedFolders, item.id]);
            }
            this.updateItems_ = true;
            this.invalidate();
            return true;
        }
        return false;
    }
    expandToFolder(folderId) {
        // Find all parent folders and expand them
        const parentsToExpand = [];
        let currentId = folderId;
        while (currentId) {
            const folder = BaseModel_1.default.byId(this.folders, currentId);
            if (!folder)
                break;
            const parentId = (0, trash_1.getDisplayParentId)(folder, this.folders.find((f) => f.id === folder.parent_id));
            if (parentId) {
                parentsToExpand.unshift(parentId);
                currentId = parentId;
            }
            else {
                break;
            }
        }
        // Expand all parent folders
        const collapsedFolders = Setting_1.default.value('collapsedFolderIds');
        const newCollapsed = collapsedFolders.filter((id) => !parentsToExpand.includes(id));
        Setting_1.default.setValue('collapsedFolderIds', newCollapsed);
        this.updateItems_ = true;
        this.invalidate();
    }
}
exports.default = FolderListWidget;
//# sourceMappingURL=FolderListWidget.js.map