/**
 * Operaciones sobre carpetas del launcher (crear, insertar app, validación).
 */
(function (global) {
    'use strict';

    var LM = null;
    function getLM() {
        LM = global.GridLauncher && global.GridLauncher.layoutModel;
        return LM;
    }

    function newFolderId() {
        if (global.crypto && typeof global.crypto.randomUUID === 'function') {
            return global.crypto.randomUUID();
        }
        return 'f_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 11);
    }

    /**
     * Crea carpeta con dos apps: quita ambas del orden top-level y añade entrada folder.
     */
    function createFolderFromApps(layout, appStableIdA, appStableIdB, defaultName) {
        var m = getLM();
        if (!m) throw new Error('GridLauncher.layoutModel missing');
        var L = m.normalizeLayout(layout);
        if (appStableIdA === appStableIdB) return { layout: L, folderId: null, error: 'same_app' };

        var idxA = -1;
        var idxB = -1;
        L.order.forEach(function (slot, i) {
            if (slot.kind === 'app') {
                if (slot.appStableId === appStableIdA) idxA = i;
                if (slot.appStableId === appStableIdB) idxB = i;
            }
        });
        if (idxA === -1 || idxB === -1) return { layout: L, folderId: null, error: 'slot_not_found' };

        var lo = Math.min(idxA, idxB);
        var hi = Math.max(idxA, idxB);
        var newOrder = L.order.slice();
        newOrder.splice(hi, 1);
        newOrder.splice(lo, 1);

        var folderId = newFolderId();
        var name = defaultName || m.DEFAULT_FOLDER_NAME;
        L.folders = Object.assign({}, L.folders);
        L.folders[folderId] = {
            name: name,
            color: m.DEFAULT_FOLDER_COLOR,
            appStableIds: [appStableIdA, appStableIdB],
            updatedAt: Date.now()
        };

        var folderSlot = { kind: 'folder', folderId: folderId };
        newOrder.splice(lo, 0, folderSlot);
        L.order = newOrder;
        return { layout: L, folderId: folderId, error: null };
    }

    function insertAppIntoFolder(layout, folderId, appStableId) {
        var m = getLM();
        var L = m.normalizeLayout(layout);
        var f = L.folders[folderId];
        if (!f) return { layout: L, error: 'folder_missing' };
        var ids = (f.appStableIds || []).slice();
        if (ids.indexOf(appStableId) !== -1) return { layout: L, error: 'already_inside' };
        ids.push(appStableId);
        L.folders = Object.assign({}, L.folders);
        L.folders[folderId] = Object.assign({}, f, {
            appStableIds: ids,
            updatedAt: Date.now()
        });
        L.order = L.order.filter(function (slot) {
            if (slot.kind === 'app' && slot.appStableId === appStableId) return false;
            return true;
        });
        return { layout: L, error: null };
    }

    function updateFolderMeta(layout, folderId, patch) {
        var m = getLM();
        var L = m.normalizeLayout(layout);
        var f = L.folders[folderId];
        if (!f) return { layout: L, error: 'folder_missing' };
        L.folders = Object.assign({}, L.folders);
        var next = Object.assign({}, f);
        if (typeof patch.name === 'string') {
            var n = patch.name.trim();
            if (n) next.name = n;
        }
        if (patch.color && m.isValidHexColor(patch.color)) next.color = patch.color;
        next.updatedAt = Date.now();
        L.folders[folderId] = next;
        return { layout: L, error: null };
    }

    function deleteFolderIfEmpty(layout, folderId) {
        var m = getLM();
        var L = m.normalizeLayout(layout);
        var f = L.folders[folderId];
        if (!f) return { layout: L, error: 'folder_missing' };
        var ids = f.appStableIds || [];
        if (ids.length > 0) return { layout: L, error: 'not_empty' };
        L.folders = Object.assign({}, L.folders);
        delete L.folders[folderId];
        L.order = L.order.filter(function (slot) {
            return !(slot.kind === 'folder' && slot.folderId === folderId);
        });
        return { layout: L, error: null };
    }

    function removeFolderAndUnpack(layout, folderId) {
        var m = getLM();
        var L = m.normalizeLayout(layout);
        var f = L.folders[folderId];
        if (!f) return { layout: L, error: 'folder_missing' };
        var ids = (f.appStableIds || []).slice();
        L.folders = Object.assign({}, L.folders);
        delete L.folders[folderId];
        var idx = -1;
        L.order.forEach(function (slot, i) {
            if (slot.kind === 'folder' && slot.folderId === folderId) idx = i;
        });
        if (idx === -1) return { layout: L, error: 'slot_missing' };
        var newSlots = ids.map(function (sid) {
            return { kind: 'app', appStableId: sid };
        });
        var o = L.order.slice();
        o.splice.apply(o, [idx, 1].concat(newSlots));
        L.order = o;
        return { layout: L, error: null };
    }

    global.GridLauncher = global.GridLauncher || {};
    global.GridLauncher.folderService = {
        newFolderId: newFolderId,
        createFolderFromApps: createFolderFromApps,
        insertAppIntoFolder: insertAppIntoFolder,
        updateFolderMeta: updateFolderMeta,
        deleteFolderIfEmpty: deleteFolderIfEmpty,
        removeFolderAndUnpack: removeFolderAndUnpack
    };
})(typeof window !== 'undefined' ? window : this);
