<?php

namespace App\Controller;

use Doctrine\Persistence\ManagerRegistry;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as FOSRest;
use OpenApi\Annotations as OA;
use Symfony\Component\HttpFoundation\Request;

use App\Entity\Bookmark;

class RestController extends AbstractFOSRestController
{

    /**
     * login
     *
     * @FOSRest\Get("/rest/login")
     * @OA\Response(
     *     response=200,
     *     description="Permet de tester l'accès à ninegate"
     *     )
     * )
     * @OA\Parameter(
     *     name="key",
     *     in="header",
     *     required=true,
     *     description="APIKey",
     *     @OA\Schema(type="string")
     * )
     */

    public function login(Request $request)
    {
        $key=$request->headers->get('key');
        $output=[];

        // Vérification de la clé
        $realkey = $this->getParameter("app_secret");
        if($key!=$realkey) {
            $view = $this->view("API Key inconnue", 403);
            return $this->handleView($view);
        }

        $view = $this->view("API Key OK", 200);
        return $this->handleView($view);
    }

    /**
     * user
     *
     * @FOSRest\Get("/rest/user/{login}")
     * @OA\Response(
     *     response=200,
     *     description="Récupération des informations d'un utilisateur"
     *     )
     * )
     * @OA\Parameter(
     *     name="key",
     *     in="header",
     *     required=true,
     *     description="APIKey",
     *     @OA\Schema(type="string")
     * )
     * @OA\Parameter(
     *     name="only",
     *     in="header",
     *     required=false,
     *     description="liste des informations désirés = user, items, bookmarks, groups, alerts, calendars\npar défaut tout",
     *     @OA\Schema(type="string")
     * )
     * @OA\Parameter(
     *     name="ssoitems",
     *     in="header",
     *     required=false,
     *     description="liste des items issu du ssoitems",
     *     @OA\Schema(type="string")
     * )
     */

    public function user($login, Request $request, ManagerRegistry $em)
    {
        $key=$request->headers->get('key');
        $only=($request->headers->get('only')?explode(",",$request->headers->get('only')):"");
        $ssoitems=($request->headers->get('ssoitems')?explode(",",$request->headers->get('ssoitems')):[]);

        // Vérification de la clé
        $realkey = $this->getParameter("app_secret");
        if($key!=$realkey) {
            $view = $this->view("API Key inconnue", 403);
            return $this->handleView($view);
        }

        $output = [];

        // Récupérer l'utilisateur
        $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$login]);
        if(!$user) {
            $output["error"]="user not exist";
            return new Response(json_encode($output), 400);
        }

        // Format de sortie
        if($only==""||in_array("user",$only))           $output["user"]             = [];
        if($only==""||in_array("bookmarks",$only))      $output["bookmarks"]        = [];
        if($only==""||in_array("items",$only))          $output["items"]            = [];
        if($only==""||in_array("items",$only))          $output["itemcategorys"]    = [];
        if($only==""||in_array("groups",$only))         $output["groups"]           = [];
        if($only==""||in_array("alerts",$only))         $output["alerts"]           = [];
        if($only==""||in_array("alerts",$only))         $output["alertcategorys"]   = [];
        if($only==""||in_array("calendars",$only))      $output["calendars"]        = [];
        if($only==""||in_array("calendars",$only))      $output["calendarevents"]   = [];
        
        $bookmarks=null;
        $items=null;
        $itemcategorys=null;
        $weburl="https://".$this->getParameter("weburl")."/".$this->getParameter("alias");

        $em->getRepository("App\Entity\Item")->getUserItems($user,$bookmarks,$items,$itemcategorys,null,$ssoitems,4);
        //$this->getDoctrine()->getRepository("App\Entity\Page")->getPagesUser($user,null,$entity,$pagesuser,$pagesadmin,$groupsshared);

        // Construction de la réponse
        if($only==""||in_array("user",$only)) {
            $output["user"]["firstname"]    = $user->getFirstname();
            $output["user"]["lastname"]     = $user->getLastname();
            $output["user"]["email"]        = $user->getEmail();
            $output["user"]["avatar"]       = $weburl."uploads/avatar/".$user->getAvatar();
            $output["user"]["niveau01"]     = $user->getNiveau01()->getLabel();
            $output["user"]["niveau02"]     = ($user->getNiveau02()?$user->getNiveau02()->getLabel():null);
            $output["user"]["role"]         = $user->getRole();
        }

        if($only==""||in_array("bookmarks",$only)) {
            if($bookmarks) {
                foreach($bookmarks as $bookmark) {
                    $tmp=[];
                    $tmp["id"]          = $bookmark->getId();
                    $tmp["title"]       = $bookmark->getTitle();
                    $tmp["url"]         = $bookmark->getUrl();
                    $tmp["target"]      = $bookmark->getTarget();
                    $tmp["item"]        = ($bookmark->getItem()?$bookmark->getItem()->getId():null);
                    $tmp["order"]       = 0;
                    $tmp["color"]       = "#".($bookmark->getColor()?$bookmark->getColor():$this->get('session')->get('color')["main"]);
                    $tmp["icon"]        = $weburl.($bookmark->getIcon()?$bookmark->getIcon()->getLabel():"uploads/icon/icon_pin.png");

                    array_push($output["bookmarks"],$tmp);
                }
            }
        }

        if($only==""||in_array("items",$only)) {
            if($items) {
                foreach($items as $item) {
                    $tmp=[];
                    $tmp["id"]          = $item->getId();
                    $tmp["title"]       = $item->getTitle();
                    $tmp["url"]         = $item->getUrl();
                    $tmp["target"]      = $item->getTarget();
                    $tmp["order"]       = $item->getRoworder();
                    $tmp["color"]       = "#".($item->getColor()?$item->getColor():$this->get('session')->get('color')["main"]);
                    $tmp["icon"]        = $weburl.($item->getIcon()?$item->getIcon()->getLabel():"uploads/icon/icon_pin.png");
                    $tmp["essential"]   = $item->getEssential();
                    $tmp["category"]    = $item->getItemcategory()->getId();

                    array_push($output["items"],$tmp);
                }
            }

            if($itemcategorys) {
                foreach($itemcategorys as $itemcategory) {
                    $tmp=[];
                    $tmp["id"]          = $itemcategory->getId();
                    $tmp["title"]       = $itemcategory->getLabel();
                    $tmp["order"]       = $itemcategory->getRoworder();
                    $tmp["color"]       = "#".($itemcategory->getColor()?$itemcategory->getColor():$this->get('session')->get('color')["main"]);

                    array_push($output["itemcategorys"],$tmp);
                }
            }
        }

        if($only==""||in_array("groups",$only)) {
            foreach($user->getGroups() as $usergroup) {
                $tmp=[];
                $tmp["id"]          = $usergroup->getGroup()->getId();
                $tmp["title"]       = $usergroup->getGroup()->getLabel();

                array_push($output["groups"],$tmp);
            }
        }

        if($only==""||in_array("alerts",$only)) {
            $alerts=$em->getRepository("App\Entity\Alert")->getUserAlerts($user,null,null,$ssoitems);
            foreach($alerts as $alert) {
                $tmp=[];
                $tmp["id"]          = $alert->getId();
                $tmp["title"]       = $alert->getTitle();
                $tmp["order"]       = $alert->getRoworder();
                $tmp["category"]    = $alert->getAlertcategory()->getId();
                $tmp["description"] = $alert->getContent();
                $tmp["fghideable"]  = $alert->getFghideable();

                array_push($output["alerts"],$tmp);
            }

            $alertcategorys=$em->getRepository("App\Entity\Alertcategory")->findAll();
            foreach($alertcategorys as $alertcategory) {
                $tmp=[];
                $tmp["id"]          = $alertcategory->getId();
                $tmp["title"]       = $alertcategory->getLabel();
                $tmp["color"]       = "#".($alertcategory->getColor()?$alertcategory->getColor():$this->get('session')->get('color')["main"]);
                $tmp["icon"]        = $weburl.($alertcategory->getIcon()?$alertcategory->getIcon()->getLabel():"uploads/icon/icon_pin.png");

                array_push($output["alertcategorys"],$tmp);
            }
        }

        if($only==""||in_array("calendars",$only)) {

            $events=$em->getRepository("App\Entity\Calendarevent")->getUserCalendarevents($user,$this->get('session')->get('color')["main"],null,null,$firstcalendar);
            foreach($events as $event) {
                $tmp=[];
                $tmp["id"]          = $event["id"];
                $tmp["title"]       = $event["title"];
                $tmp["description"] = $event["description"];
                $tmp['start']       = $event["start"];
                $tmp['end']         = $event["end"];
                $tmp['allday']      = $event["allDay"];
                $tmp['calendar']    = $event["calendar"];

                array_push($output["calendarevents"],$tmp);

                $tmp=[];
                $tmp["id"]          = $event["calendar"];
                $tmp["title"]       = $event["name"];
                $tmp["color"]       = $event["color"];

                if(!in_array($tmp,$output["calendars"]))
                    array_push($output["calendars"],$tmp);
            }
        }



        
        // Retour
        $view = $this->view($output, 200);
        return $this->handleView($view);
    }    


    /**
     * users
     *
     * @FOSRest\Get("/rest/users")
     * @OA\Response(
     *     response=200,
     *     description="Liste l'ensemble des utilisateurs de ninegate et retourne ses attributs"
     *     )
     * )
     * @OA\Parameter(
     *     name="key",
     *     in="header",
     *     required=true,
     *     description="APIKey",
     *     @OA\Schema(type="string")
     * )
     */
    public function users(Request $request, ManagerRegistry $em)
    {
        $key=$request->headers->get('key');

        // Vérification de la clé
        $realkey = $this->getParameter("app_secret");
        if($key!=$realkey) {
            $view = $this->view("API Key inconnue", 403);
            return $this->handleView($view);
        }

        $weburl="https://".$this->getParameter("weburl")."/".$this->getParameter("alias");

        $output = [];

        $users=$em->getRepository('App\Entity\User')->findAll();

        foreach($users as $user) {
            // Construction de la réponse
            $output[$user->getId()]["id"]          = $user->getId();
            $output[$user->getId()]["username"]    = $user->getUsername();
            $output[$user->getId()]["firstname"]   = $user->getFirstname();
            $output[$user->getId()]["lastname"]    = $user->getLastname();
            $output[$user->getId()]["email"]       = $user->getEmail();
            $output[$user->getId()]["avatar"]      = $weburl."uploads/avatar/".$user->getAvatar();
            $output[$user->getId()]["role"]        = $user->getRole();
        }

        // Retour
        $view = $this->view($output, 200);
        return $this->handleView($view);
    }

    /**
     * groups
     *
     * @FOSRest\Get("/rest/groups")
     * @OA\Response(
     *     response=200,
     *     description="Liste l'ensemble des groupes de ninegate et retourne ses attributs ainsi que les membres des groupes en question"
     *     )
     * )
     * @OA\Parameter(
     *     name="key",
     *     in="header",
     *     required=true,
     *     description="APIKey",
     *     @OA\Schema(type="string")
     * )
     */

    public function groups(Request $request, ManagerRegistry $em)
    {
        $key=$request->headers->get('key');

        // Vérification de la clé
        $realkey = $this->getParameter("app_secret");
        if($key!=$realkey) {
            $view = $this->view("API Key inconnue", 403);
            return $this->handleView($view);
        }

        $output = [];

        $groups=$em->getRepository('App\Entity\Group')->findAll();

        foreach($groups as $group) {
            // Construction de la réponse
            $output[$group->getId()]["id"]      = $group->getId();
            $output[$group->getId()]["name"]    = $group->getLabel();
            $output[$group->getId()]["users"]   = [];

            $usergroups=$group->getUsers();
            foreach($usergroups as $usergroup) {
                $user=$usergroup->getUser();
                $output[$group->getId()]["users"][$user->getId()]["id"]=$user->getId();
                $output[$group->getId()]["users"][$user->getId()]["username"]=$user->getUsername();
            }
        }

        // Retour
        $view = $this->view($output, 200);
        return $this->handleView($view);    
    }


    /**
     * bookmarkadd
     *
     * @FOSRest\Post("/rest/bookmark/add")
     * @OA\Response(
     *     response=200,
     *     description="Ajout d'un item ninegate existant comme bookmark d'un utilisateur"
     *     )
     * )
     * @OA\Parameter(
     *     name="key",
     *     in="header",
     *     required=true,
     *     description="APIKey",
     *     @OA\Schema(type="string")
     * )
     * @OA\Parameter(
     *     name="login",
     *     in="header",
     *     required=true,
     *     description="uid de l'utilisateur sur lequel on souhaite ajouter un bookmark",
     *     @OA\Schema(type="string")
     * )
     * @OA\Parameter(
     *     name="iditem",
     *     in="header",
     *     required=true,
     *     description="id de l'item ninegate qui doit etre ajouté en tant que bookmark",
     *     @OA\Schema(type="string")
     * )
     */
    public function bookmarkadd(Request $request, ManagerRegistry $em) {
        $key=$request->headers->get('key');
        $login=$request->headers->get('login');
        $iditem=$request->headers->get('iditem');
        
        // Vérification de la clé
        $realkey = $this->getParameter("app_secret");
        if($key!=$realkey) {
            $view = $this->view("API Key inconnue", 403);
            return $this->handleView($view);
        }

        // Tester l'existance du login
        $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$login]);
        if(!$user) {
            $view = $this->view("user not exist", 400);
            return $this->handleView($view);            
        }        

        // Tester l'existance de l'item
        $item=$em->getRepository('App\Entity\Item')->find($iditem);
        if(!$item) {
            $view = $this->view("item not exist", 400);
            return $this->handleView($view); 
        }    
        
        $bookmark = $em->getRepository('App\Entity\Bookmark')->findOneBy(["user"=>$user,"item"=>$item]);
        if(!$bookmark) {
            $bookmark = new Bookmark();
            $bookmark->setTitle($item->getTitle());
            $bookmark->setSubtitle($item->getSubtitle());
            $bookmark->setUrl($item->getUrl());
            $bookmark->setIcon($item->getIcon());
            $bookmark->setColor($item->getColor());
            $bookmark->setTarget($item->getTarget());
            $bookmark->setItem($item);
            $bookmark->setUser($user);

            $em->getManager()->persist($bookmark);
            $em->getManager()->flush();            
        }
        $output=$bookmark->getId();   

        $view = $this->view($output, 200);
        return $this->handleView($view); 
    }

    /**
     * bookmarkdel
     *
     * @FOSRest\Delete("/rest/bookmark/del")
     * @OA\Response(
     *     response=200,
     *     description="Suppression  d'un bookmark"
     *     )
     * )
     * @OA\Parameter(
     *     name="key",
     *     in="header",
     *     required=true,
     *     description="APIKey",
     *     @OA\Schema(type="string")
     * )
     * @OA\Parameter(
     *     name="idbookmark",
     *     in="header",
     *     required=true,
     *     description="id du bookmark à supprimer",
     *     @OA\Schema(type="string")
     * )
     */    
    public function bookmarkdel(Request $request, ManagerRegistry $em) {
      
        $key=$request->headers->get('key');
        $idbookmark=$request->headers->get('idbookmark');
        
        // Vérification de la clé
        $realkey = $this->getParameter("app_secret");
        if($key!=$realkey) {
            $view = $this->view("API Key inconnue", 403);
            return $this->handleView($view);
        }

        // Tester l'existance du bookmark
        $bookmark=$em->getRepository('App\Entity\Bookmark')->find($idbookmark);
        if(!$bookmark) {
            $view = $this->view("bookmark not exist", 400);
            return $this->handleView($view);               
        }    
        $em->getManager()->remove($bookmark);
        $em->getManager()->flush();        
        
        $output=[];
        $view = $this->view($output, 200);
        return $this->handleView($view);  
    }

    /**
     * alerthide
     *
     * @FOSRest\Post("/rest/alert/hide")
     * @OA\Response(
     *     response=200,
     *     description="Cache une alert à un utilisateur"
     *     )
     * )
     * @OA\Parameter(
     *     name="key",
     *     in="header",
     *     required=true,
     *     description="APIKey",
     *     @OA\Schema(type="string")
     * )
     * @OA\Parameter(
     *     name="login",
     *     in="header",
     *     required=true,
     *     description="uid de l'utilisateur sur lequel on souhaite masquer une alerte",
     *     @OA\Schema(type="string")
     * )
     * @OA\Parameter(
     *     name="idalert",
     *     in="header",
     *     required=true,
     *     description="id de l'alert à chacher",
     *     @OA\Schema(type="string")
     * )
     */ 
    public function alerthide(Request $request, ManagerRegistry $em) {
        $key=$request->headers->get('key');
        $login=$request->headers->get('login');
        $idalert=$request->headers->get('idalert');
        
        // Vérification de la clé
        $realkey = $this->getParameter("app_secret");
        if($key!=$realkey) {
            $view = $this->view("API Key inconnue", 403);
            return $this->handleView($view);
        }

        // Tester l'existance du login
        $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$login]);
        if(!$user) {
            $view = $this->view("user not exist", 400);
            return $this->handleView($view);   
        }        

        // Tester l'existance de l'alert
        $alert=$em->getRepository('App\Entity\Alert')->find($idalert);
        if(!$alert) {
            $view = $this->view("alert not exist", 400);
            return $this->handleView($view);   
        }    

        // Tester que l'alert est masquable
        if(!$alert->getFghideable()) {
            $view = $this->view("alert not hideable", 400);
            return $this->handleView($view);           
        }  

        // Masquer l'alert
        if(!$alert->getReaders()->contains($user)) {
            $alert->addReader($user);
            $em->getManager()->flush();
        }  
        
        $output=[];
        $view = $this->view($output, 200);
        return $this->handleView($view);  
    }
}


