import {
    Injectable
} from '@nestjs/common'
import { FindManyOptions, Repository } from 'typeorm'
import { InjectRepository } from '@nestjs/typeorm'
import { Likes } from './entities/likes.entity'
import { PageRequest } from 'src/common/dto/page-request'
import { Users } from 'src/users/entities/users.entity'
import { Pagination, paginate } from 'nestjs-typeorm-paginate'
import { UsersService } from 'src/users/users.service'
import { el, tr } from 'date-fns/locale'

@Injectable()
export class LikesService {
    constructor(
        @InjectRepository(Likes)
        private readonly likesRepository: Repository<Likes>,
        private readonly usersService: UsersService
    ) { }

    async findAll(req: PageRequest<Likes>): Promise<Pagination<Users>> {
        const query = await this.likesRepository.createQueryBuilder()
            .select()
            .where('likes.isValid = true')

        if (req.search) {
            const searchOptions = req.search as FindManyOptions<Likes>;
            if ('where' in req.search) {
                if ('where' in searchOptions && searchOptions.where) {
                    for (const [key, value] of Object.entries(searchOptions.where)) {
                        query.andWhere(`likes.${key} = ${value}`);
                    }
                }
            }

            if ('order' in req.search) {
                if ('order' in searchOptions && searchOptions.order) {
                    for (const [key, value] of Object.entries(searchOptions.order)) {
                        query.addOrderBy(`likes.${key}`, value as 'ASC' | 'DESC');
                    }
                }
            }
        }

        const page = await paginate<Likes>(query, { ...req.page })

        const userIds: number[] = []
        page.items.forEach(likes => {
            userIds.push(likes.userId)
        })

        const newItems = await this.usersService.findInfoByIds(userIds)
        const result: Pagination<Users> = {
            items: newItems,
            meta: page.meta
        };

        return result
    }

    async like(targetId: number, userId: number, type: number): Promise<Likes> {
        let likes = await this.likesRepository.createQueryBuilder()
            .where('userId = :userId', { userId })
            .andWhere('targetId = :targetId', { targetId })
            .andWhere('type = :type', { type })
            .getOne()
        if (likes) {
            likes.isValid = !likes.isValid
        } else {
            likes = new Likes
            likes.targetId = targetId
            likes.userId = userId
            likes.type = type
        }
        return await this.likesRepository.save(likes)
    }

}