import { Injectable } from '@nestjs/common';
import { plainToClass } from 'class-transformer';
import { PageDto, PaginattionMapper } from 'upsti-lib-common';

import { {{moduleName}} } from '../entities/{{toLowerCase moduleName}}.entity';

import { Create{{moduleName}}DTO } from './dtos/{{toLowerCase moduleName}}-create.dto';
import { Update{{moduleName}}DTO } from './dtos/{{toLowerCase moduleName}}-update.dto';
import { Response{{moduleName}}DTO } from './dtos/{{toLowerCase moduleName}}-response.dto';
import { Search{{moduleName}}DTO } from './dtos/{{toLowerCase moduleName}}-search.dto';

@Injectable()
export class {{moduleName}}Mapper extends PaginattionMapper {
  async entityRequestDTO(entity: {{moduleName}}): Promise<Response{{moduleName}}DTO> {
    return plainToClass(Response{{moduleName}}DTO, entity, {
      excludeExtraneousValues: true,
    });
  }

  async entitiesDTO(entity: {{moduleName}}[]): Promise<Response{{moduleName}}DTO[]> {
    return entity.map((items) => {
    return plainToClass(Response{{moduleName}}DTO, items, {
      excludeExtraneousValues: true,
    });
    });
  }
  
  async entityDTO(entity: {{moduleName}}): Promise<Response{{moduleName}}DTO> {
      return plainToClass(Response{{moduleName}}DTO, entity, {
        excludeExtraneousValues: true,
      });
  }

  async page2Dto( 
    request: Search{{moduleName}}DTO, 
    page: PageDto<{{moduleName}}>,
  ): Promise<PageDto<Response{{moduleName}}DTO>> {
    const {{toLowerCase moduleName}}Dto = await Promise.all(
      page.data.map(async (item) => {
        return await this.entityDTO(item);
      }),
    );
    return this.createPageDto(page, request, {{toLowerCase moduleName}}Dto);
  }

  async createDTOEntity(dto: Create{{moduleName}}DTO): Promise<{{moduleName}}> {
    return plainToClass({{moduleName}}, dto);
  }

  async updateDTOEntity(
    exist{{moduleName}}: {{moduleName}},
    request: Update{{moduleName}}DTO,
  ): Promise<{{moduleName}}> {
    const update{{moduleName}} = plainToClass({{moduleName}}, request);
    return Object.assign(exist{{moduleName}}, update{{moduleName}});
  }
}
