<?php

namespace Webkul\DamBundle\Repository;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Pim\Component\Catalog\Query\Filter\Operators;
use Webkul\DamBundle\Listener\ClassDefinationForCompatibility;
$versionCompatiblility = new ClassDefinationForCompatibility();
$versionCompatiblility->createClassAliases();

/**
 * AssetRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class AssetRepository extends EntityRepository implements \DatagridRepositoryInterface, \MassActionRepositoryInterface, \IdentifiableObjectRepositoryInterface
{
    /** @var EntityManager */
    protected $em;

    /** @var string */
    protected $entityName;

    /**
     * @param EntityManager $em
     * @param string        $class
     */
    public function __construct(EntityManager $em, $class)
    {
        parent::__construct($em, $em->getClassMetadata($class));

        $this->em = $em;
        $this->entityName = $class;
    }

    /**
     * {@inheritdoc}
     */
    public function createDatagridQueryBuilder()
    {
        $qb = $this->createQueryBuilder('wem');

        return $qb;
    }

    /**
     * {@inheritdoc}
     *
     * @param QueryBuilder $queryBuilder
     */
    public function applyMassActionParameters($qb, $inset, array $values)
    {
        if ($values) {
            $rootAlias = $qb->getRootAlias();
            $valueWhereCondition =
                $inset
                    ? $qb->expr()->in($rootAlias, $values)
                    : $qb->expr()->notIn($rootAlias, $values);
            $qb->andWhere($valueWhereCondition);
        }

        if (null !== $qb->getDQLPart('where')) {
            $whereParts = $qb->getDQLPart('where')->getParts();
            $qb->resetDQLPart('where');

            foreach ($whereParts as $part) {
                if (!is_string($part) || !strpos($part, 'entityIds')) {
                    $qb->andWhere($part);
                }
            }
        }

        $qb->setParameters(
            $qb->getParameters()->filter(
                function ($parameter) {
                    return $parameter->getName() !== 'entityIds';
                }
            )
        );
        $qb->resetDQLPart('orderBy');
    }

    /**
     * {@inheritdoc}
     */
    public function deleteFromIds(array $identifiers)
    {
        if (empty($identifiers)) {
            throw new \LogicException('No mappings to remove');
        }

        $qb = $this->createQueryBuilder('wem');

        $qb->where('wem.id IN(:identifiers)')
           ->setParameter('identifiers', $identifiers);
             
        $results = $qb->getQuery()->getResult();
        $count = 0;
        foreach ($results as $result) {
            foreach ($result->getMedias() as $media) {
                $this->em->remove($media);
            }

            $this->em->remove($result);
            $this->em->flush();
            $count++;
        }
        
        return $count;
    }

    /**
     * {@inheritdoc}
     */
    public function deleteFromNotInIds(array $identifiers, $filters)
    {
        if (empty($identifiers)) {
            throw new \LogicException('No mappings to remove');
        }

        $qb = $this->createQueryBuilder('wem');

        $qb->where('wem.id NOT IN(:identifiers)')
           ->setParameter('identifiers', $identifiers);

        if(isset($filters['code'])) {
            $qb->andWhere('wem.code LIKE :code')
           ->setParameter('code', '%'.$filters['code'].'%');
        }

        if(isset($filters['starred'])) {
            $qb->andWhere('wem.starred LIKE :starred')
           ->setParameter('starred', $filters['starred']);
        }
                
        $results = $qb->getQuery()->getResult();

        $count = 0;
        foreach ($results as $result) {
            foreach ($result->getMedias() as $media) {
                $this->em->remove($media);
            }

            $this->em->remove($result);
            $this->em->flush();
            $count++;
        }
        
        return $count;
    }



    public function getSingleArrayResultByCode($identifier)
    {
        $result = $this->getEntityManager()->createQueryBuilder()
                        ->select('a, m')
                        ->from($this->getEntityName(), 'a')
                        ->leftJoin('a.medias', 'm')
                        ->where('a.code = :identifier')
                        ->setParameter('identifier', $identifier)
                        ->getQuery()->getArrayResult();

        $result = count($result) !== 0 ? $result[0] : null;

        // if(isset($result['medias']) && count($result['medias']) === 1) {
        //     $result['medias'] = reset($result['medias']);
        // }

        return $result;
    }
    
    public function getAllDamMediasFilePath()
    {
        $result = $this->getEntityManager()->createQueryBuilder()
                        ->select('m.filePath')
                        ->from($this->getEntityName(), 'a')
                        ->leftJoin('a.medias', 'm')
                        ->getQuery()->getArrayResult();

        return $result;
    }

    public function getArrayResultsByIdentifiers($identifiers)
    {
        $result = $this->getEntityManager()->createQueryBuilder()
                        ->select('a,m')
                        ->from($this->getEntityName(), 'a')
                        ->leftJoin('a.medias', 'm')
                        ->andWhere('a.code IN (:identifiers)')
                        ->setParameter('identifiers', $identifiers)
                        ->orderBy('m.filePath')
                        ->getQuery()->getArrayResult();

                   
        return $result;
    }

    public function applyCategoryFilter($qb, $operator, $value)
    {
        $qb->andWhere('category.code IN' . ' (:wk_value)')
           ->setParameter('wk_value', $value);
    }

    /**
     * {@inheritdoc}
     */
    public function findOneByIdentifier($identifier)
    {
        return $this->findOneBy(['code' => $identifier]);
    }

    /**
     * {@inheritdoc}
     */
    public function getIdentifierProperties()
    {
        return ['code'];
    }
}
