import { Injectable , BadRequestException } from '@nestjs/common' ; import { InjectRepository } from '@nestjs/typeorm' ; import { ObjectId } from 'mongodb' ; import { Validator } from 'class-validator' ; import { CategoriesRepository } from 'src/shared/Repositories/categories.repository' ; import { CategoriesEntity } from 'src/shared/Entities/categories.entity' ; import { serializerService , ISerializeResponse } from 'src/shared/Services/serializer.service' ; import { CreateCategoryDto } from '../Dto/create-category.dto' ; import { UpdateCategoryDto } from '../Dto/update-category.dto' ; import { EntriesRepository } from 'src/shared/Repositories/entries.repository' ; import { TitlesRepository } from 'src/shared/Repositories/title.repository' ; import { StatusOk } from 'src/shared/Types' ; @ Injectable ( ) export class CategoryService { private validator : Validator ; constructor ( @ InjectRepository ( CategoriesRepository ) private readonly categoriesRepository , @ InjectRepository ( EntriesRepository ) private readonly entriesRepository , @ InjectRepository ( TitlesRepository ) private readonly titlesRepository ) { this . validator = new Validator ( ) ; } async getCategory ( categoryId ) { if ( ! this . validator . isMongoId ( categoryId ) ) throw new BadRequestException ( 'Id must be a type of MongoId' ) ; const category = await this . categoriesRepository . getCategory ( categoryId ) ; return serializerService . serializeResponse ( 'category_detail' , category ) ; } async getMainCategories ( ) { const result = await this . categoriesRepository . getMainCategories ( ) ; return serializerService . serializeResponse ( 'category_list' , result ) ; } async getChildCategories ( categoryId ) { const result = await this . categoriesRepository . getChildCategories ( categoryId ) ; return serializerService . serializeResponse ( 'category_list' , result ) ; } async getTrendingCategories ( ) { const latestEntries = await this . entriesRepository . getLatestEntries ( ) ; const topTitlesOfLatestEntries = [ ... latestEntries . entries . reduce ( ( previous , current ) => { if ( ! previous . has ( current . title_id ) ) previous . set ( current . title_id , { id : current . title_id , entryCount : 1 } ) ; else previous . get ( current . title_id ) . entryCount ++ ; return previous ; } , new Map ) . values ( ) ] ; const topFiveTitlesIds = topTitlesOfLatestEntries . sort ( ( x , y ) => y . entryCount - x . entryCount ) . slice ( 0 , 5 ) ; const idList = topFiveTitlesIds . map ( item => ObjectId ( item . id ) ) ; const topFiveTitles = await this . titlesRepository . getTitleListByIds ( idList ) ; const categoryIdList = topFiveTitles . titles . map ( item => ObjectId ( item . category_id ) ) ; const trendingCategories = await this . categoriesRepository . getCategoryListByIds ( categoryIdList ) ; return serializerService . serializeResponse ( 'trending_categories' , trendingCategories ) ; } async createCategory ( dto ) { const newCategory = await this . categoriesRepository . createCategory ( dto ) ; return serializerService . serializeResponse ( 'category_detail' , newCategory ) ; } async updateCategory ( categoryId , dto ) { if ( ! this . validator . isMongoId ( categoryId ) ) throw new BadRequestException ( 'Id must be a type of MongoId' ) ; const category = await this . categoriesRepository . updateCategory ( categoryId , dto ) ; return serializerService . serializeResponse ( 'category_detail' , category ) ; } async deleteCategory ( categoryId ) { if ( ! this . validator . isMongoId ( categoryId ) ) throw new BadRequestException ( 'Id must be a type of MongoId' ) ; await this . categoriesRepository . deleteCategory ( categoryId ) ; return { status : 'ok' , message : 'Category has been deleted' } ; } }