<?php
namespace Webkul\UVDesk\CoreFrameworkBundle\Services;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Webkul\UVDesk\CoreFrameworkBundle\Entity\AgentActivity;
use Webkul\UVDesk\CoreFrameworkBundle\Entity\User;
use Webkul\UVDesk\CoreFrameworkBundle\Entity\Thread;

class ReportService {

    const LIMIT = 15;
    const TICKET_GLOBAL_ACCESS = 1;
    const TICKET_GROUP_ACCESS = 2;
    const TICKET_TEAM_ACCESS  = 3;
    const DEFAULT_PAGINATION_LIMIT = 15;

	private $request;
	protected $container;
    protected $em;

    protected $currentUser = null;

    public $endDate = null;
    public $startDate = null;
    public $parameters = array();
    public $safeFields = array('page','limit','sort','order','direction');

	public function __construct(EntityManagerInterface $em, RequestStack $request, ContainerInterface $container)
    {
        $this->em = $em;
        $this->request = $request;
        $this->container = $container;
    }

    public function getAgentActivity(array $agents, $from = null, $to = null)
{
    $activityQuery = $this->em->createQueryBuilder()
    ->select(
        't.id AS id, 
         tic.id AS ticketId, 
         CONCAT(agent.firstName, \' \', agent.lastName) AS fullName, 
         CONCAT(customer.firstName, \' \', customer.lastName) AS customerName, 
         t.timeSpent AS timeSpent, 
         tt.code AS code, 
         tic.createdAt AS createdAt'
    )
    ->from(\Webkul\UVDesk\CoreFrameworkBundle\Entity\Thread::class, 't')
    ->join('t.ticket', 'tic')
    // Join the customer entity. If your Ticket entity defines a customer relation, use:
    ->join('tic.customer', 'customer')
    // Otherwise, if the relation isn’t mapped, you can join manually as shown below:
    // ->join(\Webkul\UVDesk\CoreFrameworkBundle\Entity\User::class, 'customer', \Doctrine\ORM\Query\Expr\Join::WITH, 'tic.customerId = customer.id')
    ->join('tic.agent', 'agent')
    ->join(
        \Webkul\UVDesk\CoreFrameworkBundle\Entity\TicketType::class, 
        'tt', 
        \Doctrine\ORM\Query\Expr\Join::WITH, 
        'tt.id = t.typeId'
    )
    ->where('tic.createdAt BETWEEN :startDate AND :endDate')
    ->setParameter('startDate', $from)
    ->setParameter('endDate', $to)
    ->orderBy('tic.createdAt', 'DESC');

if (!empty($agents)) {
    // Filter results based on the provided agent IDs.
    $activityQuery->andWhere('agent.id IN (:agentIds)')
                  ->setParameter('agentIds', $agents, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
}

return $activityQuery;
}

    public function addPermissionFilter($qb, $container, $haveJoin = true)
    {
        $activeUser = $this->container->get('user.service')->getSessionUser();
        $supportGroupReferences = $this->em->getRepository(User::class)->getUserSupportGroupReferences($activeUser);
        $supportTeamReferences  = $this->em->getRepository(User::class)->getUserSupportTeamReferences($activeUser);
        $userInstance = $activeUser->getAgentInstance();

        if (!empty($userInstance) && ('ROLE_AGENT' == $userInstance->getSupportRole()->getCode() && $userInstance->getTicketAccesslevel() != self::TICKET_GLOBAL_ACCESS)) {
            $qualifiedGroups = empty($this->params['group']) ? $supportGroupReferences : array_intersect($supportGroupReferences, explode(',', $this->params['group']));
            $qualifiedTeams = empty($this->params['team']) ? $supportTeamReferences : array_intersect($supportTeamReferences, explode(',', $this->params['team']));

            switch ($userInstance->getTicketAccesslevel()) {
                case self::TICKET_GROUP_ACCESS:
                    $qb
                        ->andWhere("t.agent = :agentId OR gr.id IN(:supportGroupIds) OR tSub.id IN(:supportTeamIds)")
                        ->setParameter('agentId', $activeUser->getId())
                        ->setParameter('supportGroupIds', $qualifiedGroups)
                        ->setParameter('supportTeamIds', $qualifiedTeams);
                    break;
                case self::TICKET_TEAM_ACCESS:
                    $qb
                        ->andWhere("t.agent = :agentId OR tSub.id IN(:supportTeamIds)")
                        ->setParameter('agentId', $activeUser->getId())
                        ->setParameter('supportTeamIds', $qualifiedTeams);
                    break;
                default:
                    $qb
                        ->andWhere("t.agent = :agentId")
                        ->setParameter('agentId', $activeUser->getId());
                    break;
            }
        }

        return $qb;
    }

    public function getTotalReplies($ticketIds, array $agents, $from, $to)
    {
            $agentClause = array_map(function($id) { return "thread.user = $id"; }, $agents);
            $qb = $this->em->createQueryBuilder()
                    ->select("Count(thread.id) as ticketCount, IDENTITY (thread.ticket) AS ticketId")
                    ->from(Thread::class, 'thread')
                    ->andwhere('thread.ticket IN (:ticket)')
                    ->andWhere('thread.threadType =:threadType')
                    ->andWhere('thread.createdAt BETWEEN :startDate AND :endDate');
                    if(!empty($agentClause))
                            $qb->andWhere(implode(' OR ', $agentClause));

                $qb->setParameter('threadType', 'reply')
                    ->setParameter('ticket', $ticketIds)
                    ->setParameter('startDate', $from)
                    ->setParameter('endDate', $to)
                    ->groupBy('thread.ticket');

        $threadDetails = $qb->getQuery()->getScalarResult();
        return $threadDetails;
    }

    // Convert Timestamp to day/hour/min
    function time2string($time) {
        $d = floor($time/86400);
        $_d = ($d < 10 ? '0' : '').$d;

        $h = floor(($time-$d*86400)/3600);
        $_h = ($h < 10 ? '0' : '').$h;

        $m = floor(($time-($d*86400+$h*3600))/60);
        $_m = ($m < 10 ? '0' : '').$m;

        $s = $time-($d*86400+$h*3600+$m*60);
        $_s = ($s < 10 ? '0' : '').$s;

        $time_str = "0 minutes";
        if($_d != 00)
            $time_str = $_d." ".'days';
        elseif($_h != 00)
            $time_str = $_h." ".'hours';
        elseif($_m != 00)
            $time_str = $_m." ".'minutes';


        return $time_str." "."ago";
    }

    /**
     * symfony_http_build_query Return query strinf
     * @param  Array $query Query parameters
     * @return String Query String
     */
    public function symfony_http_build_query(array $query) {
        $query['page'] = "replacePage";
        $params = array();
        if(isset($query['_locale']))
            unset($query['_locale']);
        if(isset($query['domain']))
            unset($query['domain']);
        foreach ($query as $key => $value) {
            if (!isset($value)) {
                $params[] = $key;
            } else {
                $params[] = $key . '/' . str_replace('%2F', '/', rawurlencode($value));
            }
        }
        $str = implode('/', $params);
        if(isset($query['new']))
            $str = str_replace("new/1","new",$str);
        elseif(isset($query['unassigned']))
            $str = str_replace("unassigned/1","unassigned",$str);
        elseif(isset($query['notreplied']))
            $str = str_replace("notreplied/1","notreplied",$str);
        elseif(isset($query['mine']))
            $str = str_replace("mine/1","mine",$str);
        elseif(isset($query['starred']))
            $str = str_replace("starred/1","starred",$str);
        elseif(isset($query['trashed']))
            $str = str_replace("trashed/1","trashed",$str);
        return $str;
    }
}
