import { Service, Inject, Container } from 'typedi';
import { sanitizeObjectStrings } from 'jsm-core';
import initLogger, {LoggerContext} from 'jsm-logger';

type EntityAlias = {{orAny ENTITY_TYPING_ALIAS}};

const logger = initLogger(LoggerContext.SANITIZER, '{{ENTITY_CAMELCASED_CAPITALIZED_SINGULAR}}');

{{#each MODULE.API.METHODS}}
{{#ifMethodHasSanitizer this}}
/**
  * {{serviceMethodComments this}}
  */
export async function sanitize{{this.name}}Body({{sanitizerArgs this}}): Promise<{{orAny this.requestFullName}}> {
  try {

    /**
     * @description Sanitize all string values in the object
     */
    body = sanitizeObjectStrings(body);


    {{#if this.meta.has_custom_logic}}
    /**
      * Custom sanitization logic
      */
      // TODO: Add your custom sanitization logic here
    
    
    {{else}}
    
    {{#ifIsCreateMethod this null}}
    /**
    * @description Remove all unwanted properties already set at the time of creation
    */
    [
      // all unwanted properties already set at the time of creation
      '_id',
      'tracking_id',
      'created_by',
      'created_by_original_user',
      'created_at',
      // all unwanted properties that will be set automatically
      'updated_at',
      'search_meta',
      'snapshots',
      'deliverer_data',
      'auth_meta',
      'insights',
      // security
      'is_suspended',
      'is_deleted',
      'permissions',
      'permissions_other_than_role',
    ].forEach(p => {
      Reflect.deleteProperty(body.data || {}, p);
    });
      
      
      
    /**
    * @description inject the current user id as the creator of the object
    */
    if(!body.data) body.data = {} as any;
    {{#if ENTITY_META.is_creatable}}
    body.data.created_by = authData?.current?.user?._id;
    body.data.app = authData?.current?.user?.app ? authData?.current?.user?.app : body.data.app || authData?.current?.app?._id;
    {{/if}}
    {{/ifIsCreateMethod}}

    {{#ifIsUpdateMethod this null}}
    /**
    * @description Remove all unwanted properties already set at the time of update
    */
    [
      // all unwanted properties already set at the time of update
      '_id',
      'tracking_id',
      'created_by',
      'created_by_original_user',
      'created_at',
      'app',
      'company',
      // all unwanted properties that will be set automatically
      'updated_at',
      'search_meta',
      'snapshots',
      'deliverer_data',
      'auth_meta',
      'insights',
      // security
      'email',
      'password',
      'confirm_password',
      'is_suspended',
      'is_deleted',
      'permissions',
      'permissions_other_than_role',
    ].forEach(p => {
      Reflect.deleteProperty(body, p);
    });
    {{/ifIsUpdateMethod}}
  
    {{/if}}

    {{#if ../ENTITY_META.has_location}}
    {{#ifIsCreateMethod this null}}
    /**
     * Transform location array into sphere coordinates before injecting them in the DB.
     */
    if (body.data.location && body.data.location instanceof Array) {
      body.data.location = {
        type: 'Point',
        coordinates: body.data.location
      } as any
    };
    {{/ifIsCreateMethod}}
    {{#ifIsStrictUpdateMethod this null}}
    /**
     * Transform location array into sphere coordinates before injecting them in the DB.
     */
    if (body.data.location && body.data.location instanceof Array) {
      body.data.location = {
        type: 'Point',
        coordinates: body.data.location
      } as any
    };
    {{/ifIsStrictUpdateMethod}}
    {{/if}}

    /**
     * @description return the sanitized object
     */
    return body;

  } catch (error) {
    logger.error('Error sanitizing body', error);
    throw error;
  }
}
  {{nl}}
{{/ifMethodHasSanitizer}}
{{/each}}