/**
 * KooKoa Folders — Breadcrumb & Subfolder Cards
 *
 * Extracted from admin.js (block 9).
 * IIFE that adds methods directly to FO (window.KookoaWPF).
 *
 * Depends on: kookoawpf-admin (FO.data, FO.tree, FO.treeData, FO.goToFolder,
 *             FO.getFolderId, FO._isGridMode, FO.currentFolder)
 *
 * @since 1.0.0
 */
(function($) {
    'use strict';

    const FO = window.KookoaWPF;
    if (!FO) return;

    /**
     * Initialize the breadcrumb bar and subfolder cards container.
     * Both are injected above the content area (media grid or list table).
     */
    FO.initBreadcrumb = function() {
        const self = this;

        // Skip entirely if both are disabled
        if (!self.data.showBreadcrumb && !self.data.showSubfolderCards) return;

        // Build the breadcrumb and subfolder cards elements through DOM
        // API so the localized aria-label and the breadcrumbStyle-driven
        // class never travel through an HTML literal.
        let $breadcrumb = $();
        if (self.data.showBreadcrumb) {
            $breadcrumb = $('<div id="kookoawpf-breadcrumb-bar" class="kookoawpf-breadcrumb-bar"></div>');
            if (self.data.breadcrumbStyle === 'retro') {
                $breadcrumb.addClass('kookoawpf-breadcrumb-retro');
            }
            $breadcrumb.append(
                $('<nav class="kookoawpf-breadcrumb-nav"></nav>')
                    .attr('aria-label', self.data.strings.breadcrumbLabel || 'Folder navigation')
            );
        }
        const $cards = self.data.showSubfolderCards ? $('<div id="kookoawpf-subfolder-cards" class="kookoawpf-subfolder-cards"></div>') : $();

        if (self._isGridMode()) {
            // Grid mode: insert after the .media-toolbar (the filter/Bulk Organize bar)
            const $toolbar = $('.media-frame-content .media-toolbar').first();
            if ($toolbar.length) {
                $toolbar.after($cards);
                $toolbar.after($breadcrumb);
            } else {
                // Fallback: prepend to .media-frame-content
                $('.media-frame-content').first().prepend($cards).prepend($breadcrumb);
            }
        } else {
            // List mode: insert after .tablenav.top (the filter/pagination bar)
            const $tablenav = $('.tablenav.top').first();
            if ($tablenav.length) {
                $tablenav.after($cards);
                $tablenav.after($breadcrumb);
            } else {
                $('.wp-list-table').first().before($cards).before($breadcrumb);
            }
        }

        // Initial breadcrumb/cards update happens in ready.jstree
        // when the tree data is fully loaded
    };

    /**
     * Walk the treeData recursively to find a folder by its ID.
     * Returns the node data object, or null.
     */
    FO._findFolderInTree = function(folderId, nodes) {
        if (!nodes) nodes = this.treeData;
        if (!nodes) return null;
        folderId = String(folderId);

        for (let i = 0; i < nodes.length; i++) {
            const n = nodes[i];
            const nid = String(n.data ? n.data.folder_id : (n.id || '').replace('folder_', ''));
            if (nid === folderId) return n;
            if (n.children && n.children.length) {
                const found = this._findFolderInTree(folderId, n.children);
                if (found) return found;
            }
        }
        return null;
    };

    /**
     * Build the ancestor chain (breadcrumb) for a given folder ID.
     * Returns an array of { id, text, icon, color } from root to the current folder.
     */
    FO._getBreadcrumbChain = function(folderId) {
        const self = this;
        const chain = [];

        // Walk up using jsTree parent data
        const inst = self.tree ? self.tree.jstree(true) : null;
        if (!inst) return chain;

        const nodeId = 'folder_' + folderId;
        let node = inst.get_node(nodeId);
        if (!node) return chain;

        // Collect ancestors (bottom-up) then reverse
        while (node && node.id !== '#') {
            const fid = self.getFolderId(node);
            let text = (node.data && node.data.folder_id)
                ? self.tree.find('#' + node.id + ' > .jstree-anchor .kookoawpf-folder-text').first().text()
                : '';
            if (!text) text = node.text ? node.text.replace(/<[^>]+>/g, '').trim() : '';

            chain.unshift({
                id: fid,
                text: text,
                icon: node.data ? (node.data.icon || '') : '',
                color: node.data ? (node.data.color || '#39FF14') : '#39FF14'
            });

            node = inst.get_node(node.parent);
        }

        return chain;
    };

    /**
     * Update the breadcrumb bar to reflect the current folder.
     */
    FO._updateBreadcrumb = function(folder) {
        const self = this;
        const $nav = $('.kookoawpf-breadcrumb-nav');
        if (!$nav.length) return;

        $nav.empty();

        const strs = self.data.strings;

        // "All Items" root crumb — always shown
        const $allCrumb = $('<a href="#" class="kookoawpf-crumb kookoawpf-crumb-root" data-folder="all"></a>')
            .text(strs.allItems || 'All Items');
        $nav.append($allCrumb);

        if (!folder || folder === 'all') {
            $allCrumb.addClass('kookoawpf-crumb-current');
            $('#kookoawpf-breadcrumb-bar').removeClass('kookoawpf-breadcrumb-active');
            return;
        }

        $('#kookoawpf-breadcrumb-bar').addClass('kookoawpf-breadcrumb-active');

        if (folder === 'uncategorized') {
            $nav.append('<span class="kookoawpf-crumb-sep">/</span>');
            $nav.append(
                $('<span class="kookoawpf-crumb kookoawpf-crumb-current"></span>')
                    .text(strs.uncategorized || 'Uncategorized')
            );
            return;
        }

        // Build ancestor chain
        const chain = self._getBreadcrumbChain(folder);
        if (!chain.length) return;

        for (let i = 0; i < chain.length; i++) {
            $nav.append('<span class="kookoawpf-crumb-sep">/</span>');

            const c = chain[i];
            const isLast = (i === chain.length - 1);

            let $crumb;
            if (isLast) {
                $crumb = $('<span class="kookoawpf-crumb kookoawpf-crumb-current"></span>');
            } else {
                // c.id comes from jstree's id pool (numeric folder IDs from
                // the server) but routing it through .attr() keeps the
                // dynamic value out of the HTML literal.
                $crumb = $('<a href="#" class="kookoawpf-crumb"></a>')
                    .attr('data-folder', c.id);
            }

            // Breadcrumb shows plain text only — no icons/emoji
            $crumb.append(document.createTextNode(c.text));
            $nav.append($crumb);
        }

        // Click handlers
        $nav.off('click.kwpfBreadcrumb').on('click.kwpfBreadcrumb', '.kookoawpf-crumb[data-folder]', function(e) {
            e.preventDefault();
            const fid = $(this).data('folder');
            self.goToFolder(fid);
        });
    };

    /**
     * Get the direct children of a folder from the jstree data.
     * Returns an array of { id, text, icon, color, count, is_dynamic } objects.
     */
    FO._getSubfolders = function(folderId) {
        const self = this;
        const inst = self.tree ? self.tree.jstree(true) : null;
        if (!inst) return [];

        const nodeId = 'folder_' + folderId;
        const node = inst.get_node(nodeId);
        if (!node || !node.children || !node.children.length) return [];

        const subs = [];
        for (let i = 0; i < node.children.length; i++) {
            const child = inst.get_node(node.children[i]);
            if (!child || !child.data) continue;

            let text = self.tree.find('#' + child.id + ' > .jstree-anchor .kookoawpf-folder-text').first().text();
            if (!text) text = child.text ? child.text.replace(/<[^>]+>/g, '').trim() : '';

            subs.push({
                id: child.data.folder_id,
                text: text,
                icon: child.data.icon || '',
                color: child.data.color || '#39FF14',
                count: child.data.count !== undefined ? child.data.count : '',
                is_dynamic: child.data.is_dynamic || false,
                pinned: child.data.pinned || false,
                locked: child.data.locked || false,
                hasChildren: child.children && child.children.length > 0
            });
        }
        return subs;
    };

    /**
     * Update the subfolder cards to show children of the current folder.
     */
    FO._updateSubfolderCards = function(folder) {
        const self = this;
        const $container = $('#kookoawpf-subfolder-cards');
        if (!$container.length) return;

        $container.empty().hide();

        // Only show subfolder cards when inside a numeric folder (not "all" or "uncategorized")
        if (!folder || folder === 'all' || folder === 'uncategorized' || !$.isNumeric(folder)) {
            return;
        }

        const subs = self._getSubfolders(folder);
        if (!subs.length) return;

        // Defence-in-depth hex check before s.color reaches an SVG fill
        // attribute. The server already filters with sanitize_hex_color;
        // this catches any future drift / extension data.
        function _validHex(v) {
            return ( typeof v === 'string' && /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/.test(v) ) ? v : null;
        }

        // Static SVG skeleton — no dynamic data inline. The fill (and
        // optional stroke for the all-black corner case) is set via
        // setAttribute on the parsed <path> node below.
        const FOLDER_SVG = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg">'
            + '<path d="M2 6a2 2 0 012-2h5l2 2h9a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"/>'
            + '</svg>';

        for (let i = 0; i < subs.length; i++) {
            const s = subs[i];
            const $card = $('<a href="#" class="kookoawpf-subfolder-card"></a>')
                .attr('data-folder', s.id);

            // Subfolder indicator first (rendered before the icon by CSS).
            if (s.hasChildren) {
                $card.append(
                    $('<span class="kookoawpf-card-has-children">+</span>')
                        .attr('title', self.data.strings.hasSubfolders || 'Has subfolders')
                );
            }

            // Icon — emoji branch goes through .text(); SVG branch parses a
            // static skeleton and sets fill / stroke via setAttribute.
            let $icon;
            if (s.icon) {
                $icon = $('<span class="kookoawpf-card-icon kookoawpf-card-emoji"></span>')
                    .text(String(s.icon));
            } else {
                $icon = $('<span class="kookoawpf-card-icon"></span>').html(FOLDER_SVG);
                const color = _validHex(s.color) || '#39FF14';
                const pathEl = $icon.find('path').get(0);
                if (pathEl) {
                    pathEl.setAttribute('fill', color);
                    if (color.toLowerCase() === '#000000') {
                        pathEl.setAttribute('stroke', '#39FF14');
                        pathEl.setAttribute('stroke-width', '2');
                    }
                }
            }
            $card.append($icon);

            // Name
            $card.append(
                $('<span class="kookoawpf-card-name"></span>').text(s.text)
            );

            // Pin / Lock badges — title text is hardcoded English (matches
            // the rest of the codebase) so the static markup is fine.
            if (s.pinned) {
                $card.append('<span class="kookoawpf-badge-icon kookoawpf-badge-pin" title="Pinned"><span class="dashicons dashicons-star-filled"></span></span>');
            }
            if (s.locked) {
                $card.append('<span class="kookoawpf-badge-icon kookoawpf-badge-lock" title="Locked"><span class="dashicons dashicons-lock"></span></span>');
            }

            // Count badge
            $card.append(
                $('<span class="kookoawpf-card-count"></span>').text(s.count)
            );

            $container.append($card);
        }

        $container.show();

        // Click handler
        $container.off('click.kookoawpfCards').on('click.kookoawpfCards', '.kookoawpf-subfolder-card', function(e) {
            e.preventDefault();
            const fid = $(this).data('folder');
            self.goToFolder(String(fid));
        });

        // Sync hover: card → tree
        $container.off('mouseenter.kookoawpfSync mouseleave.kookoawpfSync')
            .on('mouseenter.kookoawpfSync', '.kookoawpf-subfolder-card', function() {
                const fid = $(this).data('folder');
                $('#folder_' + fid + ' > .jstree-anchor').addClass('kookoawpf-hover-sync');
            })
            .on('mouseleave.kookoawpfSync', '.kookoawpf-subfolder-card', function() {
                const fid = $(this).data('folder');
                $('#folder_' + fid + ' > .jstree-anchor').removeClass('kookoawpf-hover-sync');
            });

        // Sync hover: tree → card
        // Use .jstree-anchor (not .jstree-node) to avoid child nodes triggering parent hover
        if (self.tree && self.tree.length) {
            self.tree.off('mouseenter.kookoawpfSync mouseleave.kookoawpfSync', '.jstree-anchor')
                .on('mouseenter.kookoawpfSync', '.jstree-anchor', function() {
                    const $node = $(this).closest('.jstree-node');
                    const nodeId = $node.attr('id');
                    if (!nodeId) return;
                    const fid = nodeId.replace('folder_', '');
                    $container.find('.kookoawpf-subfolder-card[data-folder="' + fid + '"]').addClass('kookoawpf-hover-sync');
                })
                .on('mouseleave.kookoawpfSync', '.jstree-anchor', function() {
                    const $node = $(this).closest('.jstree-node');
                    const nodeId = $node.attr('id');
                    if (!nodeId) return;
                    // Keep card highlighted while context menu is open on this node
                    if ($node.hasClass('kookoawpf-context-active')) return;
                    const fid = nodeId.replace('folder_', '');
                    $container.find('.kookoawpf-subfolder-card[data-folder="' + fid + '"]').removeClass('kookoawpf-hover-sync');
                });
        }
    };

})(jQuery);
