import { Resolver, Query, Args, ID, Info, Mutation } from '@nestjs/graphql';
import { Types } from 'mongoose';
import { User } from '@/models/user.model';
import { UsersService } from '@/users/users.service';
import { CreateUserInput } from './dto/create-user.input';
import { ListArguments } from '@/dto/list.input';
import { UpdateUserInput } from './dto/update-user.input';
import { ListUsersResponse } from './dto/list-users.response';
import graphqlFields from 'graphql-fields';
import type { GraphQLResolveInfo } from 'graphql';

@Resolver(() => User)
export class UsersResolver {

    constructor(private readonly usersService: UsersService) { }

    @Query(() => ListUsersResponse, { name: "users" })
    async getUsers(@Info() info: GraphQLResolveInfo, @Args('input') input: ListArguments): Promise<ListUsersResponse> {
        const fields = graphqlFields(info); const projection = this.usersService.buildProjection(fields?.data); const { skip, limit, sort, filters } = input;
        return await this.usersService.findAll(projection, skip, limit, sort, filters);
    }

    @Query(() => User, { name: 'user', nullable: true })
    async getUser(@Args('id', { type: () => ID }) id: string, @Info() info: GraphQLResolveInfo): Promise<User | null> {
        const fields = graphqlFields(info); const projection = this.usersService.buildProjection(fields); return this.usersService.findById(new Types.ObjectId(id), projection);
    }

    @Mutation(() => User, { name: 'createUser' })
    async createUser(@Args('input') input: CreateUserInput): Promise<User> { return this.usersService.create(input) }

    @Mutation(() => User, { name: 'updateUser' })
    async updateUser(@Args('uuid') uuid: string, @Args('input') input: UpdateUserInput): Promise<User> { return this.usersService.update(uuid, input) }

    @Mutation(() => Boolean, { name: 'deleteUser' })
    async deleteUser(@Args('uuid') uuid: string): Promise<boolean> { return this.usersService.delete(uuid) }

}
