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 { GroupAuthGuard } from '../auth/group-auth.guard';
import { Request } from 'express';

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

    @Query(() => [Agent])
    @UseGuards(GroupAuthGuard)
    listAgents() {
        return this.prismaService.agent.findMany({
            where: {
                NOT: { uid: null },
            },
        });
    }

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

        if (!agent) throw new NotFoundException('That Agent does not exist');

        return agent;
    }

    @ResolveField('entries')
    @UseGuards(GroupAuthGuard)
    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,
            },
        });

        return 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,
            };
        });
    }
}