import { inject, Injector } from '@angular/core';
import { IdentityService, InventoryService } from '@c8y/client';

async function getExternalIdentityByTargetId(targetId, identityService) {
    const targetExternalIds = await identityService.list(`${targetId}`);
    return targetExternalIds.data[0];
}
async function targetDetails(targetId, inventoryService) {
    const targetDetails = await inventoryService.detail(targetId);
    return targetDetails.data;
}
async function resolveSuggestedAsset(exportedDevice, contextDevice) {
    // 1. check if the exported device is of the same type as the context device
    if (exportedDevice.type === contextDevice.type) {
        return contextDevice;
    }
    const injector = inject(Injector);
    const identityService = injector.get(IdentityService);
    const contextAssetExternalIdentity = await getExternalIdentityByTargetId(contextDevice.id, identityService);
    // 2. check if the exported device has the same externalId as the context device
    if (contextAssetExternalIdentity?.externalId === exportedDevice.externalIdentity?.externalId) {
        return contextDevice;
    }
    // 3. If context device is a group, check if the exported device is a child of the context asset
    if (contextDevice.c8y_IsDeviceGroup) {
        const inventoryService = injector.get(InventoryService);
        const children = (await inventoryService.childAssetsList(contextDevice.id, { pageSize: 100 }))
            .data;
        const matchingChild = children.find((child) => {
            return child.id === exportedDevice.id && child.type === exportedDevice.type;
        });
        return matchingChild || null;
    }
    return null;
}

/**
 * Check if a configuration has a valid device property
 */
function hasAssetProperty(config) {
    return config && 'device' in config && config.device !== null && config.device !== undefined;
}
/**
 * Creates a device with external identity information
 */
async function createExportedAsset(device, identityService, inventoryService) {
    const deviceDetails = await targetDetails(device.id, inventoryService);
    const externalIdentity = await getExternalIdentityByTargetId(device.id, identityService);
    return { ...deviceDetails, externalIdentity };
}
/**
 * Exports a configuration with asset information enriched for export
 */
async function exportConfigWithDevice(config, _dashboardData, _options) {
    const injector = inject(Injector);
    const identityService = injector.get(IdentityService);
    const inventoryService = injector.get(InventoryService);
    // Create a new config object with all properties
    const exportedConfig = { ...config };
    if (hasAssetProperty(config) && config.device?.id) {
        exportedConfig.device = await createExportedAsset(config.device, identityService, inventoryService);
    }
    else {
        // If there's no device or no device.id, maintain the null/undefined
        exportedConfig.device = config.device;
    }
    return exportedConfig;
}
/**
 * Imports a configuration with asset information adapted to the current context
 */
async function importConfigWithDevice(config, dashboardData, _options) {
    // Create a new config object with all properties
    const importedConfig = { ...config };
    if (config.device && 'externalIdentity' in config.device) {
        const suggestedDevice = await resolveSuggestedAsset(config.device, dashboardData.context);
        // Remove externalIdentity and add suggestedDevice
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const { externalIdentity, ...deviceWithoutExternalId } = config.device;
        importedConfig.device = { ...deviceWithoutExternalId, suggestedDevice };
    }
    else {
        // If the device doesn't have externalIdentity, maintain it as is
        importedConfig.device = config.device;
    }
    return importedConfig;
}

/**
 * Helper function to check if a value is an array of objects with __target property
 */
function isTargetObjectArray(value) {
    return (Array.isArray(value) &&
        value.length > 0 &&
        typeof value[0] === 'object' &&
        value[0] !== null &&
        '__target' in value[0]);
}
/**
 * Find all property names in an object that contain arrays of objects with __target property
 */
function findTargetArrayProperties(config) {
    return Object.entries(config)
        .filter(([_, value]) => isTargetObjectArray(value))
        .map(([key]) => key);
}

/**
 * Transforms a single target object for export
 */
async function createExportedTargetObject(targetObject, identityService, inventoryService) {
    if (!targetObject.__target?.id) {
        return {
            ...targetObject,
            __target: null // Handle null case
        };
    }
    const externalIdentity = await getExternalIdentityByTargetId(targetObject.__target.id, identityService);
    const details = await targetDetails(targetObject.__target.id, inventoryService);
    return {
        ...targetObject,
        __target: {
            ...details,
            externalIdentity
        }
    };
}
/**
 * Transforms a single exported target object for import
 */
async function createImportedTargetObject(exportedTargetObject, context) {
    if (!exportedTargetObject.__target) {
        return {
            ...exportedTargetObject,
            __target: {
                suggestedDevice: null
            }
        };
    }
    const suggestedDevice = await resolveSuggestedAsset(exportedTargetObject.__target, context);
    // Create a new object without externalIdentity
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { externalIdentity, ...targetWithoutExternalId } = exportedTargetObject.__target;
    return {
        ...exportedTargetObject,
        __target: {
            ...targetWithoutExternalId,
            suggestedDevice
        }
    };
}
/**
 * Transforms an array of target objects for export
 */
async function processTargetArrayToExport(targetObjects = [], identityService, inventoryService) {
    if (!targetObjects || !Array.isArray(targetObjects)) {
        return [];
    }
    return Promise.all(targetObjects.map(obj => createExportedTargetObject(obj, identityService, inventoryService)));
}
/**
 * Transforms an array of exported target objects for import
 */
async function processExportedTargetArray(targetObjects = [], context) {
    if (!targetObjects || !Array.isArray(targetObjects)) {
        return [];
    }
    return Promise.all(targetObjects.map(obj => createImportedTargetObject(obj, context)));
}

/**
 * Exports widget configuration with all target objects transformed for export
 */
async function exportConfigWithTargets(config, _dashboardData, _options) {
    const injector = inject(Injector);
    const identityService = injector.get(IdentityService);
    const inventoryService = injector.get(InventoryService);
    // Find all properties with target arrays
    const targetArrayProperties = findTargetArrayProperties(config);
    if (targetArrayProperties.length === 0) {
        return config;
    }
    // Create a new object with all properties from the original config
    const exportedConfig = { ...config };
    // Process each target array property
    await Promise.all(targetArrayProperties.map(async (prop) => {
        exportedConfig[prop] = await processTargetArrayToExport(config[prop], identityService, inventoryService);
    }));
    return exportedConfig;
}

/**
 * Imports widget configuration with all target objects transformed for the current context
 */
async function importConfigWithTargets(config, dashboardData, _options) {
    // Find all properties with target arrays
    const targetArrayProperties = findTargetArrayProperties(config);
    if (targetArrayProperties.length === 0) {
        return config;
    }
    // Create a new object with all properties from the original config
    const importedConfig = { ...config };
    // Process each target array property
    await Promise.all(targetArrayProperties.map(async (prop) => {
        importedConfig[prop] = await processExportedTargetArray(config[prop], dashboardData.context);
    }));
    return importedConfig;
}

/**
 * Generated bundle index. Do not edit.
 */

export { exportConfigWithDevice, exportConfigWithTargets, getExternalIdentityByTargetId, hasAssetProperty, importConfigWithDevice, importConfigWithTargets, resolveSuggestedAsset, targetDetails };
//# sourceMappingURL=c8y-ngx-components-widgets-import-export-config.mjs.map
