<?php

namespace App\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\Common\Collections\ArrayCollection;

class ItemRepository extends EntityRepository
{
    public function getUserItems($user,&$bookmarks,&$itemsordered,&$itemcategorys,$iditemcategory=null,$ssoitems=[],$withbookmark=1,$fgessential=false) {
        // Profilage
        $roles=($user?$user->getRoles():["ROLE_ANONYME"]);
        $groups=($user?$user->getGroups():[]);
        $niveau01=($user?$user->getNiveau01():[]);

        // Bookmark de l'utilisateur
        $bookmarks = array();
        if($user)
            $bookmarks=$this->getEntityManager()->getRepository("App\Entity\Bookmark")->findBy(["user"=>$user]);

        
        $itemcategoryfilter=null;
        if($iditemcategory) $itemcategoryfilter=$this->getEntityManager()->getRepository("App\Entity\Itemcategory")->findBy(["id"=>$iditemcategory]);

        // Bookmark lié à un item
        $bookmarksitems=new ArrayCollection();
        if($withbookmark==0) {
            foreach($bookmarks as $bookmark) {
                if($bookmark->getItem()) $bookmarksitems->add($bookmark->getItem());
            }
        }

        // Initialisation du calcul des items
        $items=new ArrayCollection();
        $itemalls=new ArrayCollection();

        // Récupération des items par rôles
        $itemsroles=[];
        
        foreach($roles as $role) {
            $qb = $this->getEntityManager()->createQueryBuilder();
            $qb->select('item')
                ->from("App\Entity\Item", 'item')
                ->where($qb->expr()->like('item.roles', $qb->expr()->literal("%$role%")));
            
            if($iditemcategory && $itemcategoryfilter) {
                $qb->andWhere("item.itemcategory=:itemcategory")
                   ->setParameter("itemcategory",$itemcategoryfilter);
            }

            $itemsroles=$qb->getQuery()->getResult();
            foreach($itemsroles as $itemrole) {
                if(!$bookmarksitems->contains($itemrole) && !$items->contains($itemrole)) {
                    if(!$fgessential || ($fgessential && $itemrole->getEssential()))
                        $items->add($itemrole);
                }

                if(!$itemalls->contains($itemrole)) $itemalls->add($itemrole);
            }
        }

        // Récupération des items par group
        $itemsgroups=[];
        foreach($groups as $group) {
            $qb = $this->getEntityManager()->createQueryBuilder();
            $qb->select('item')
                ->from("App\Entity\Item", 'item')
                ->where(":group MEMBER OF item.groups")
                ->setParameter("group",$group->getGroup());
            
            if($iditemcategory && $itemcategoryfilter) {
                $qb->andWhere("item.itemcategory=:itemcategory")
                   ->setParameter("itemcategory",$itemcategoryfilter);
            }

            $itemsgroups=$qb->getQuery()->getResult();
            foreach($itemsgroups as $itemgroup) {
                if(!$bookmarksitems->contains($itemgroup) && !$items->contains($itemgroup)) {
                    if(!$fgessential || ($fgessential && $itemgroup->getEssential()))
                        $items->add($itemgroup);
                }

                if(!$itemalls->contains($itemgroup)) $itemalls->add($itemgroup);
            }

            
        }


        // Récupération des items par niveau01
        $itemsniveau01s=[];
        if($niveau01) {
            $qb = $this->getEntityManager()->createQueryBuilder();
            $qb->select('item')
                ->from("App\Entity\Item", 'item')
                ->where(":niveau01 MEMBER OF item.niveau01s")
                ->setParameter("niveau01",$niveau01);
            
            if($iditemcategory && $itemcategoryfilter) {
                $qb->andWhere("item.itemcategory=:itemcategory")
                   ->setParameter("itemcategory",$itemcategoryfilter);
            }

            $itemsniveau01s=$qb->getQuery()->getResult();
            foreach($itemsniveau01s as $itemniveau01) {
                if(!$bookmarksitems->contains($itemniveau01) && !$items->contains($itemniveau01)) {
                    if(!$fgessential || ($fgessential && $itemniveau01->getEssential()))
                        $items->add($itemniveau01);
                }

                if(!$itemalls->contains($itemniveau01)) $itemalls->add($itemniveau01);
            }
        }

        // Récupération des items par ssoitem
        $itemsssoitems=[];
        if(is_array($ssoitems)) {
            foreach($ssoitems as $ssoitem) {
                $qb = $this->getEntityManager()->createQueryBuilder();
                $qb->select('item')
                    ->from("App\Entity\Item", 'item')
                    ->where("item.ssoitem=:ssoitem ")
                    ->setParameter("ssoitem",$ssoitem);
                
                if($iditemcategory && $itemcategoryfilter) {
                    $qb->andWhere("item.itemcategory=:itemcategory")
                    ->setParameter("itemcategory",$itemcategoryfilter);
                }

                $itemsssoitems=$qb->getQuery()->getResult();
                foreach($itemsssoitems as $itemssoitem) {
                    if(!$bookmarksitems->contains($itemssoitem) && !$items->contains($itemssoitem)) {
                        if(!$fgessential || ($fgessential && $itemssoitem->getEssential()))
                            $items->add($itemssoitem);
                    }

                    if(!$itemalls->contains($itemssoitem)) $itemalls->add($itemssoitem);
                }
            }
        }

        // Pour chaque bookmark lié à un item : on vérifie qu'il est tjr la permission de voir cet item sinon on l'enlève de ses fav
        foreach($bookmarks as $key => $bookmark) {
            $item=$bookmark->getItem();
            if($item) {
                if(!$itemalls->contains($item) ) {
                    unset($bookmarks[$key]); 
                }
            }
        }


        // Trie des items
        $itemsordered = $items->getIterator();
        $itemsordered->uasort(function ($first, $second) {
            if((int) $first->getRowOrder() > (int) $second->getRowOrder())
                $return=1;
            elseif((int) $first->getRowOrder() == (int) $second->getRowOrder()) {
                if($first->getTitle() > $second->getTitle())
                    $return=1;
                else
                    $return=-1;
            }
            else
                $return=-1;

            return $return;
        });

        // Catégories affichées
        $itemcategorys = $this->getEntityManager()->getRepository('App\Entity\Itemcategory')->findBy([], ['rowOrder' => 'asc']);
        if($iditemcategory && $itemcategoryfilter) $itemcategorys = $itemcategoryfilter;
        
        switch($withbookmark) {
            // items uniquement
            case 1: $bookmarks=null; break;

            // bookmarks uniquement
            case 2: $itemsordered=null; break;

        }        

        return $itemsordered;
    }
}
