/**
 * Integración grid launcher: filas de vista, tiles y puntero/arrastre.
 * main.js inyecta callbacks (abrir app, guardar layout, menú contextual).
 */
(function (global) {
    'use strict';

    var LM = function () {
        return global.GridLauncher && global.GridLauncher.layoutModel;
    };
    var FS = function () {
        return global.GridLauncher && global.GridLauncher.folderService;
    };
    var GD = function () {
        return global.GridLauncher && global.GridLauncher.gridDrag;
    };
    var PI = function () {
        return global.GridLauncher && global.GridLauncher.pointerInteraction;
    };

    function buildDisplayRows(apps, appsToShow, launcherLayout, getStableId, isFiltering, searchQuery) {
        var m = LM();
        if (!m) return { rows: [], prependSystem: [] };
        var rows = m.resolveGridRows({
            apps: apps,
            launcherLayout: launcherLayout,
            getStableId: getStableId,
            appsToShow: appsToShow,
            isFiltering: isFiltering,
            searchQuery: searchQuery || ''
        });
        var resolvedSids = {};
        rows.forEach(function (r) {
            if (r.kind === 'app') resolvedSids[getStableId(r.app)] = true;
        });
        var prependSystem = [];
        appsToShow.forEach(function (app) {
            if (!app || !app.isSystemApp) return;
            var sid = getStableId(app);
            if (!resolvedSids[sid]) prependSystem.push({ kind: 'app', app: app, indexInApps: apps.indexOf(app), orderIndex: -1, prepend: true });
        });
        return { rows: rows, prependSystem: prependSystem };
    }

    function createAppTile(app, realIndex, orderIndex, savedGridTextColor, getTypeBadgeHtml, getStableId) {
        var appItem = document.createElement('div');
        appItem.className = 'app-item';
        if (app.isSystemApp) appItem.classList.add('recycle-bin-app');
        appItem.dataset.index = realIndex >= 0 ? realIndex : -1;
        appItem.dataset.orderIndex = String(orderIndex);
        appItem.dataset.appStableId = getStableId(app);
        appItem.dataset.slotKind = 'app';
        appItem.tabIndex = 0;
        var tooltipText = app.title;
        if (app.description && app.description.trim() !== '') tooltipText += '\n' + app.description;
        if (app.category && app.category !== 'Sistema') tooltipText += '\nCategoría: ' + app.category;
        appItem.setAttribute('data-tooltip', tooltipText);
        appItem.innerHTML =
            '<img src="' +
            app.icon +
            '" alt="' +
            String(app.title).replace(/"/g, '&quot;') +
            '" class="app-icon" draggable="false">' +
            '<p style="color: ' +
            savedGridTextColor +
            ';">' +
            app.title +
            '</p>' +
            getTypeBadgeHtml(app);
        return appItem;
    }

    function createFolderTile(folderId, folder, orderIndex, savedGridTextColor, apps, getStableId) {
        var el = document.createElement('div');
        el.className = 'app-item folder-tile';
        el.dataset.index = '-1';
        el.dataset.orderIndex = String(orderIndex);
        el.dataset.folderId = folderId;
        el.dataset.slotKind = 'folder';
        el.tabIndex = 0;
        var col = folder.color || '#5c6bc0';
        el.style.setProperty('--launcher-folder-color', col);
        var ids = folder.appStableIds || [];
        var previews = ids.slice(0, 4);
        var mini = previews
            .map(function (sid) {
                var f = LM().findAppByStableId(apps, sid, getStableId);
                return f && f.app && f.app.icon
                    ? '<img class="folder-mini-icon" src="' + String(f.app.icon).replace(/"/g, '&quot;') + '" alt="" draggable="false">'
                    : '<span class="folder-mini-placeholder"></span>';
            })
            .join('');
        el.setAttribute('data-tooltip', folder.name || 'Carpeta');
        el.innerHTML =
            '<div class="folder-tile-inner" style="--folder-accent:' +
            col +
            '">' +
            '<div class="folder-icon-stack">' +
            mini +
            '</div>' +
            '<p style="color: ' +
            savedGridTextColor +
            ';">' +
            String(folder.name || 'Carpeta').replace(/</g, '&lt;') +
            '</p>' +
            '</div>';
        return el;
    }

    /**
     * @param {object} api
     */
    function bindLauncherToTile(el, row, api) {
        var m = LM();
        var gd = GD();
        var pi = PI();
        var fs = FS();
        if (!m || !gd || !pi || !fs) return null;

        var isFolder = row.kind === 'folder';
        var app = row.kind === 'app' ? row.app : null;
        var folderId = isFolder ? row.folderId : null;
        var folder = isFolder ? row.folder : null;
        var orderIndex = row.orderIndex;
        var appStableId = app ? api.getAppStableId(app) : null;

        var suppress = function () {
            // La supresión debe cubrir "clic sostenido + arrastre + soltar".
            api.suppressNextClick(1400);
        };

        var openContextMenu = function (e) {
            if (isFolder) {
                api.onFolderContextMenu(e, folderId, folder);
            } else {
                api.onAppContextMenu(e, app, row.indexInApps);
            }
        };

        var dragAllowed = !api.isDragDisabled() && orderIndex >= 0;

        var ghostWrap = null;
        var dragOffsetX = 0;
        var dragOffsetY = 0;

        var onDragStart = dragAllowed
            ? function (e) {
                  ghostWrap = gd.createDragGhost(el, api.appGrid);
                  var rect = el.getBoundingClientRect();
                  dragOffsetX = e.clientX - rect.left;
                  dragOffsetY = e.clientY - rect.top;
                  ghostWrap.move(e.clientX, e.clientY, dragOffsetX, dragOffsetY);
                  api.onDragHighlight(null);
                  api.onDragHighlight(el);
              }
            : null;

        var onDragMove = dragAllowed
            ? function (e) {
                  if (!ghostWrap) return;
                  ghostWrap.move(e.clientX, e.clientY, dragOffsetX, dragOffsetY);
                  var target = gd.getGridItemAtPoint(api.appGrid, e.clientX, e.clientY, el);
                  api.onDragHighlight(target);
              }
            : null;

        var onDragEnd = dragAllowed
            ? function (e) {
                  // Asegurar que el click posterior al drop no abra la app.
                  suppress();
                  api.onDragHighlight(null);
                  if (ghostWrap) {
                      ghostWrap.destroy();
                      ghostWrap = null;
                  }
                  var target = gd.getGridItemAtPoint(api.appGrid, e.clientX, e.clientY, el);
                  api.onGridDrop({
                      sourceEl: el,
                      targetEl: target,
                      row: row,
                      clientX: e.clientX,
                      clientY: e.clientY
                  });
              }
            : null;

        var ctrl = pi.createController({
            element: el,
            // Drag: mantener presionado para iniciar arrastre (mouse/touch).
            longPressMs: api.longPressMs(),
            moveThresholdPx: api.moveThresholdPx(),
            // En PC: reordenamiento solo desde el icono con clic sostenido.
            mouseLongPressAction: 'drag',
            dragHandleSelector: '.app-icon, .folder-icon-stack',
            // En móvil: tap sostenido para arrastrar; a los 1s menú contextual del app si NO hay drag.
            touchLongPressAction: 'drag',
            menuLongPressMs: 1000,
            isDisabled: function () {
                return !!api.previewActive();
            },
            onLongPressMenu: function (e) {
                if (app && app.isSystemApp) return;
                openContextMenu(e);
            },
            onDragStart: onDragStart,
            onDragMove: onDragMove,
            onDragEnd: onDragEnd,
            onSuppressClick: suppress
        });

        el.addEventListener(
            'click',
            function (e) {
                if (Date.now() < api.getSuppressUntil()) {
                    e.preventDefault();
                    e.stopPropagation();
                    return;
                }
                if (isFolder) {
                    e.preventDefault();
                    api.onFolderOpen(folderId, folder);
                    return;
                }
                api.onAppClick(e, app, row.indexInApps);
            },
            true
        );

        el.addEventListener('contextmenu', function (e) {
            if (app && app.isSystemApp) {
                e.preventDefault();
                e.stopPropagation();
                return;
            }
            e.preventDefault();
            e.stopPropagation();
            openContextMenu(e);
        });

        el.addEventListener('focus', function () {
            if (!isFolder && app) {
                api.onTileFocus(row.indexInApps, el);
            }
        });

        return ctrl;
    }

    global.GridLauncher = global.GridLauncher || {};
    global.GridLauncher.integration = {
        buildDisplayRows: buildDisplayRows,
        createAppTile: createAppTile,
        createFolderTile: createFolderTile,
        bindLauncherToTile: bindLauncherToTile
    };
})(typeof window !== 'undefined' ? window : this);
