import { Args, Context, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql';
import { Agent } from './models/agent.model';
import { PrismaService } from '../prisma/prisma.service';
import { GraphQLString } from 'graphql';
import { NotFoundException, UseGuards } from '@nestjs/common';
import { GraphQLAuthGuard } from 'src/auth/graphql-auth.guard';
import { Request } from 'express';

@Resolver(() => Agent)
@UseGuards(GraphQLAuthGuard)
export class AgentResolver {
    constructor(private prismaService: PrismaService) {}

    @Query(() => [Agent])
    listAgents(@Context() { req }: { req: Request }) {
        return this.prismaService.agent.findMany();
    }

    @Query(() => Agent)
    async getAgent(
        @Args({ name: 'code', type: () => GraphQLString }) code: string,
    ) {
        const agent = await this.prismaService.agent.findFirst({
            where: { slug: code },
        });

        if (!agent) throw new NotFoundException();

        return agent;
    }

    @ResolveField('entries')
    async entries(
        @Parent() entry: Agent,
        @Context() { req }: { req: Request },
    ) {
        const unlocks = await this.prismaService.group.findFirst({
            where: { id: req.group.id },
            select: {
                unlocks: true,
            },
        })
            .then(value => value.unlocks)
            .then(unlocks => unlocks.map(value => value.id));

        const result = await this.prismaService.agent.findFirst({
            where: {
                id: entry.id,
            },
            include: { 
                entries: true,
            },
        });

        const entries = result.entries.map(entry => {
            if (!entry.private || unlocks.includes(entry.id))
                return {
                    ...entry,
                    locked: false,
                };

            return {
                id: entry.id,
                agentId: entry.agentId,
                private: true,
                createdAt: entry.createdAt,
                locked: true,
            };
        });

        return entries;
    }
}