<?php

declare(strict_types=1);

namespace App\Module\TimeTracking\Infrastructure\Mcp\Tool;

use App\Module\TimeTracking\Domain\Repository\TimeEntryRepositoryInterface;
use App\Shared\Infrastructure\Mcp\Serializer;
use DateTimeImmutable;
use Mcp\Capability\Attribute\McpTool;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

#[McpTool(name: 'list-time-entries', description: 'List time entries with optional filters. Duration is computed in minutes and null for active timers.')]
class ListTimeEntriesTool
{
    public function __construct(
        private readonly TimeEntryRepositoryInterface $timeEntryRepository,
        private readonly Security $security,
    ) {}

    public function __invoke(
        ?int $userId = null,
        ?int $projectId = null,
        ?int $taskId = null,
        ?string $startDate = null,
        ?string $endDate = null,
        int $limit = 100,
    ): string {
        if (!$this->security->isGranted('ROLE_USER')) {
            throw new AccessDeniedException('Access denied: ROLE_USER required.');
        }

        $limit = min($limit, 200);

        $qb = $this->timeEntryRepository->createQueryBuilder('te')
            ->leftJoin('te.user', 'u')->addSelect('u')
            ->leftJoin('te.project', 'p')->addSelect('p')
            ->leftJoin('te.task', 't')->addSelect('t')
            ->leftJoin('te.tags', 'tg')->addSelect('tg')
            ->orderBy('te.startedAt', 'DESC')
            ->setMaxResults($limit)
        ;

        if (null !== $userId) {
            $qb->andWhere('u.id = :userId')->setParameter('userId', $userId);
        }
        if (null !== $projectId) {
            $qb->andWhere('p.id = :projectId')->setParameter('projectId', $projectId);
        }
        if (null !== $taskId) {
            $qb->andWhere('t.id = :taskId')->setParameter('taskId', $taskId);
        }
        if (null !== $startDate) {
            $qb->andWhere('te.startedAt >= :startDate')
                ->setParameter('startDate', new DateTimeImmutable($startDate.' 00:00:00'))
            ;
        }
        if (null !== $endDate) {
            $qb->andWhere('te.startedAt <= :endDate')
                ->setParameter('endDate', new DateTimeImmutable($endDate.' 23:59:59'))
            ;
        }

        $entries = $qb->getQuery()->getResult();

        return json_encode(array_map(Serializer::timeEntry(...), $entries));
    }
}
