import { Restricted, RoleEnum, equalIds, mapClasses } from '@lenne.tech/nest-server';
import { Field, ObjectType } from '@nestjs/graphql';
import { Schema as MongooseSchema, Prop, SchemaFactory } from '@nestjs/mongoose';
import { Document, Schema } from 'mongoose';<%- props.imports %>

import { PersistenceModel } from '../../common/models/persistence.model';
import { User } from '../user/user.model';

export type <%= props.namePascal %>Document = <%= props.namePascal %> & Document;

/**
 * <%= props.namePascal %> model
 */
@Restricted(RoleEnum.ADMIN)
@ObjectType({ description: '<%= props.namePascal %>' })
@MongooseSchema({ timestamps: true })
export class <%= props.namePascal %> extends PersistenceModel {

  // ===================================================================================================================
  // Properties
  // ===================================================================================================================
  <%- props.props %>

  // ===================================================================================================================
  // Methods
  // ===================================================================================================================

  /**
   * Initialize instance with default values instead of undefined
   */
  override init() {
    super.init();
    // this.propertyName = [];
    return this;
  }

  /**
   * Map input
   *
   * Hint: Non-primitive variables should always be mapped (see mapClasses / mapClassesAsync in ModelHelper)
   */
  override map(input) {
    super.map(input);
    // return mapClasses(input, { propertyName: PropertyModel }, this);
    return <%- props.mappings %>
  }

  /**
   * Verification of the user's rights to access the properties of this object
   *
   * Check roles, prepare or remove properties
   * Return undefined if the whole object should not be returned or throw an exception to stop the whole request
   */
  override securityCheck(user: User, force?: boolean) {
    // In force mode or for admins everything is allowed
    if (force || user?.hasRole(RoleEnum.ADMIN)) {
      return this;
    }

    // Usually only the creator has access to the object
    if (!equalIds(user, this.createdBy)) {
      return undefined;
    }

    // Check permissions for properties of this object and return the object afterward
    return this;
  }
}

export const <%= props.namePascal %>Schema = SchemaFactory.createForClass(<%= props.namePascal %>);
