<?php

declare(strict_types=1);

namespace App\Controller;

use App\Entity\ComposantConstructeurLink;
use App\Entity\Constructeur;
use App\Entity\MachineConstructeurLink;
use App\Entity\PieceConstructeurLink;
use App\Entity\ProductConstructeurLink;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

final class ConstructeurStatsController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $em,
    ) {}

    #[Route('/api/constructeurs/{id}/stats', name: 'api_constructeur_stats', methods: ['GET'])]
    public function stats(string $id): JsonResponse
    {
        $this->denyAccessUnlessGranted('ROLE_VIEWER');

        $constructeur = $this->em->find(Constructeur::class, $id);
        if (!$constructeur) {
            return new JsonResponse(
                ['message' => 'Fournisseur introuvable.'],
                Response::HTTP_NOT_FOUND,
            );
        }

        $bulk = $this->fetchAllStats();

        return new JsonResponse($bulk[$id] ?? [
            'composantCount' => 0,
            'pieceCount'     => 0,
            'machineCount'   => 0,
            'productCount'   => 0,
        ]);
    }

    #[Route('/api/constructeurs/stats', name: 'api_constructeurs_stats_bulk', methods: ['GET'], priority: 1)]
    public function bulkStats(): JsonResponse
    {
        $this->denyAccessUnlessGranted('ROLE_VIEWER');

        return new JsonResponse($this->fetchAllStats());
    }

    /** @return array<string, array{composantCount: int, pieceCount: int, machineCount: int, productCount: int}> */
    private function fetchAllStats(): array
    {
        $result = [];

        // Initialize all constructeurs with zero counts
        $allIds = $this->em->createQuery(
            'SELECT c.id FROM App\Entity\Constructeur c',
        )->getSingleColumnResult();

        foreach ($allIds as $id) {
            $result[$id] = [
                'composantCount' => 0,
                'pieceCount'     => 0,
                'machineCount'   => 0,
                'productCount'   => 0,
            ];
        }

        // 4 bulk queries instead of 4N
        $counts = [
            'composantCount' => ComposantConstructeurLink::class,
            'pieceCount'     => PieceConstructeurLink::class,
            'machineCount'   => MachineConstructeurLink::class,
            'productCount'   => ProductConstructeurLink::class,
        ];

        foreach ($counts as $key => $entityClass) {
            $rows = $this->em->createQuery(
                'SELECT IDENTITY(l.constructeur) AS cid, COUNT(l.id) AS cnt FROM '.$entityClass.' l GROUP BY l.constructeur',
            )->getResult();

            foreach ($rows as $row) {
                if (isset($result[$row['cid']])) {
                    $result[$row['cid']][$key] = (int) $row['cnt'];
                }
            }
        }

        return $result;
    }
}
