import { GsbEntityService, GsbEntityDef, GsbProperty, EntityDefService } from '@gsb-core/core';
import { SchemaManagerService } from '@gsb-core/core';

const entityDefService = EntityDefService.getInstance(false);
const schemaManagerService = SchemaManagerService.getInstance(false);

export const gsbEntityDefTools = {
    /**
     * Gets common property definitions that can be used when creating entity properties
     */
    getCommonPropertyDefs: async ({ token, tenantCode }: { token?: string; tenantCode?: string }) => {
        return EntityDefService.PROPERTY_DEFINITIONS;
    },

    /**
     * Creates a new entity definition with the specified schema
     */
    createEntityDef: async ({ entityDef, token, tenantCode }: { entityDef: GsbEntityDef; token?: string; tenantCode?: string }) => {
        try {
            const result = await entityDefService.createEntityDef(entityDef, token, tenantCode);
            return {
                id: result,
                success: true
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    },

    /**
     * Updates an existing entity definition
     */
    updateEntityDef: async ({ entityDef, token, tenantCode }: { entityDef: GsbEntityDef; token?: string; tenantCode?: string }) => {
        try {
            if (!entityDef.id) {
                return { success: false, error: 'Entity definition ID is required for update' };
            }
            const result = await entityDefService.updateEntityDef(entityDef, token, tenantCode);
            return {
                success: result
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    },

    /**
     * Adds a new property to an entity definition
     */
    addProperty: async ({ property, entityDef, token, tenantCode }: { property: GsbProperty; entityDef?: GsbEntityDef; token?: string; tenantCode?: string }) => {
        try {
            const result = await entityDefService.addProperty( property, entityDef, token, tenantCode);
            return {
                success: result
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    },

    /**
     * Removes a property from an entity definition
     */
    removeProperty: async ({ property, entityDef, token, tenantCode }: { property: GsbProperty; entityDef?: GsbEntityDef; token?: string; tenantCode?: string }) => {
        try {
            const result = await entityDefService.removeProperty(property, entityDef, token, tenantCode);
            return {
                success: result
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    },

    /**
     * Updates an existing property in an entity definition
     */
    updateProperty: async ({ property, entityDef, token, tenantCode }: { property: GsbProperty; entityDef?: GsbEntityDef; token?: string; tenantCode?: string }) => {
        try {
            // Ensure the property has the propertyName value set
            const result = await entityDefService.updateProperty(property, entityDef, token, tenantCode);
            return {
                success: result
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    },

    /**
     * Gets an entity definition by ID
     */
    getEntityDef: async ({ entityDef, token, tenantCode }: { entityDef: GsbEntityDef; token?: string; tenantCode?: string }) => {
        try {
            const result = await entityDefService.getEntityDef(entityDef, token, tenantCode);
            return {
                entityDef: result,
                success: true
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    },

    /**
     * Queries entity definitions
     */
    queryEntityDefs: async ({ searchTerm, page, pageSize, includeSystem, token, tenantCode }: { searchTerm: string; page: number; pageSize: number; includeSystem?: boolean; token?: string; tenantCode?: string }) => {
        try {
            const result = await entityDefService.searchEntityDefs(searchTerm, page, pageSize, includeSystem, token, tenantCode);
            return {
                ...result,
                success: true
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    },

    /**
     * Creates or updates schema entities and properties
     */
    createOrUpdateSchema: async ({ entityDefs, token, tenantCode }: { entityDefs: any[]; token?: string; tenantCode?: string }) => {
        try {
            const result = await schemaManagerService.createOrUpdateSchema(entityDefs, token || '', tenantCode || '');
            return {
                ...result,
                success: true
            }
        } catch (error: any) {
            return {
                ...error,
                success: false
            }
        }
    }
}