<?php

namespace App\Repository;

use App\Entity\Client;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @extends ServiceEntityRepository<Client>
 */
class ClientRepository extends AbstractRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Client::class);
    }

    public function findClientsByOrganizationalUnitAndDescendants(int $organizationalUnitId, array $filters = []): array
    {
        $entityManager = $this->getEntityManager();

        $query = $entityManager->createQuery(
            'SELECT o.path
         FROM App\Entity\OrganizationalUnit o
         WHERE o.id = :id'
        )->setParameter('id', $organizationalUnitId);

        $result = $query->getOneOrNullResult();
        if (!$result) {
            return [];
        }

        $path = $result['path'] . '/%';

        $query = $entityManager->createQuery(
            'SELECT o.id
         FROM App\Entity\OrganizationalUnit o
         WHERE o.id = :id OR o.path LIKE :path'
        )
            ->setParameter('id', $organizationalUnitId)
            ->setParameter('path', $path);

        $unitIds = array_column($query->getArrayResult(), 'id');

        $qb = $entityManager->createQueryBuilder();
        $qb->select('c')
            ->from('App\Entity\Client', 'c')
            ->where('c.organizationalUnit IN (:unitIds)')
            ->setParameter('unitIds', $unitIds);

        foreach ($filters as $key => $value) {
            if ($key === 'order' || $key === 'page' || $key === 'itemsPerPage' || $key === 'organizationalUnit.id') {
                continue;
            }

            if ($key === 'exists') {
                foreach ($value as $field => $existsValue) {
                    if ($existsValue === 'true') {
                        $qb->andWhere("c.$field IS NOT NULL");
                    } elseif ($existsValue === 'false') {
                        $qb->andWhere("c.$field IS NULL");
                    }
                }
            } elseif ($key === 'name') {
                // Aplicar búsqueda con LIKE para el campo "name"
                $qb->andWhere("c.name LIKE :name")
                    ->setParameter('name', "%$value%");
            } elseif ($key === 'query') {
                // Búsqueda en múltiples campos (name, ip, mac)
                $qb->andWhere($qb->expr()->orX(
                    $qb->expr()->like('c.name', ':searchQuery'),
                    $qb->expr()->like('c.ip', ':searchQuery'),
                    $qb->expr()->like('c.mac', ':searchQuery')
                ))->setParameter('searchQuery', "%$value%");
            } else {
                // Búsqueda exacta para otros campos
                $qb->andWhere("c.$key = :$key")->setParameter($key, $value);
            }
        }



        if (isset($filters['order']) && is_array($filters['order'])) {
            foreach ($filters['order'] as $field => $direction) {
                if (in_array(strtolower($direction), ['asc', 'desc'])) {
                    $qb->addOrderBy("c.$field", $direction);
                }
            }
        }

        if (isset($filters['page']) && isset($filters['itemsPerPage'])) {
            $page = max(1, (int) $filters['page']);
            $itemsPerPage = max(1, (int) $filters['itemsPerPage']);
            $qb->setFirstResult(($page - 1) * $itemsPerPage)
                ->setMaxResults($itemsPerPage);
        }

        return $qb->getQuery()->getResult();
    }

    public function countClientsByOrganizationalUnitAndDescendants(int $organizationalUnitId, array $filters = []): int
    {
        $entityManager = $this->getEntityManager();

        // Obtener el path de la unidad organizativa raíz
        $query = $entityManager->createQuery(
            'SELECT o.path FROM App\Entity\OrganizationalUnit o WHERE o.id = :id'
        )->setParameter('id', $organizationalUnitId);

        $result = $query->getOneOrNullResult();
        if (!$result) {
            return 0;
        }

        $path = $result['path'] . '/%';

        $query = $entityManager->createQuery(
            'SELECT o.id FROM App\Entity\OrganizationalUnit o WHERE o.id = :id OR o.path LIKE :path'
        )
            ->setParameter('id', $organizationalUnitId)
            ->setParameter('path', $path);

        $unitIds = array_column($query->getArrayResult(), 'id');

        $qb = $entityManager->createQueryBuilder();
        $qb->select('COUNT(c.id)')
            ->from('App\Entity\Client', 'c')
            ->where('c.organizationalUnit IN (:unitIds)')
            ->setParameter('unitIds', $unitIds);

        foreach ($filters as $key => $value) {
            if ($key === 'order' || $key === 'page' || $key === 'itemsPerPage' || $key === 'organizationalUnit.id') {
                continue;
            }

            if ($key === 'exists') {
                foreach ($value as $field => $existsValue) {
                    if ($existsValue === 'true') {
                        $qb->andWhere("c.$field IS NOT NULL");
                    } elseif ($existsValue === 'false') {
                        $qb->andWhere("c.$field IS NULL");
                    }
                }
            } elseif ($key === 'name') {
                $qb->andWhere("c.name LIKE :name")
                    ->setParameter('name', "%$value%");
            } elseif ($key === 'query') {
                $qb->andWhere($qb->expr()->orX(
                    $qb->expr()->like('c.name', ':searchQuery'),
                    $qb->expr()->like('c.ip', ':searchQuery'),
                    $qb->expr()->like('c.mac', ':searchQuery')
                ))->setParameter('searchQuery', "%$value%");
            } else {
                $qb->andWhere("c.$key = :$key")->setParameter($key, $value);
            }
        }

        return (int) $qb->getQuery()->getSingleScalarResult();
    }



}
