<?php

namespace AppBundle\Controller\Admin;

use AppBundle\Entity\ConnectionHistory;
use AppBundle\Entity\Port;
use AppBundle\Entity\PortHistory;
use AppBundle\Form\Type\PortType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class PortController extends Controller
{
    /**
     * @Template()
     *
     * @param Request $request
     * @return array
     */
    public function listAction(Request $request)
    {
        $em = $this->getDoctrine();
        $query = $em->getRepository('AppBundle:Port')->getListQuery();

        $paginator = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query,
            $request->query->get('page', 1),
            20,
            array('defaultSortFieldName' => 'p.name', 'defaultSortDirection' => 'desc')
        );

        return array(
            'pagination' => $pagination
        );
    }

    /**
     * @param Request $request
     * @return array
     */
    public function createAction(Request $request)
    {
        $port = new Port();
        $form = $this->createForm(new PortType(), $port);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($port);

            $portHistory = new PortHistory();
            $portHistory
                ->setName($port->getName())
                ->setCountry($port->getCountry())
                ->setUser($this->getUser())
                ->setPort($port);

            $em->persist($portHistory);
            $em->flush();

            $this->container->get('app.service.json')->generateJson();
            
            return $this->redirect($this->generateUrl('app_admin.port.list'));
        }

        return $this->render(
            'AppBundle:Admin/Port:form.html.twig',
            array(
                'form' => $form->createView()
            )
        );
    }

    /**
     * @param Request $request
     * @param Port $port
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function editAction(Request $request, Port $port)
    {
        if($port->getIsRemoved()) {
            throw new AccessDeniedException();
        }

        $portClone = clone($port);
        $form = $this->createForm(new PortType(), $port);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->flush();

            $this->savePortEditHistory($portClone, $port);

            $this->container->get('app.service.json')->generateJson();
            
            return $this->redirect($this->generateUrl('app_admin.port.list'));
        }

        return $this->render(
            'AppBundle:Admin/Port:form.html.twig',
            array(
                'port' => $port,
                'form' => $form->createView()
            )
        );
    }

    /**
     * @param Port $port
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function removeAction(Port $port)
    {
        if($port->getIsRemoved()) {
            throw new AccessDeniedException();
        }

        $em = $this->getDoctrine()->getManager();
        $port->setIsRemoved(true);

        $portHistory = new PortHistory();
        $portHistory
            ->setUser($this->getUser())
            ->setPort($port)
            ->setIsRemoved(true);

        $em->persist($portHistory);

        $connections = array_merge($port->getLoadings()->toArray(), $port->getUnloadings()->toArray());

        foreach($connections as $connection) {
            $connection->setIsRemoved(true);

            $connectionHistory = new ConnectionHistory();
            $connectionHistory
                ->setUser($this->getUser())
                ->setConnection($connection)
                ->setIsRemoved(true);

            $em->persist($connectionHistory);
        }

        $em->flush();
        
        $this->container->get('app.service.json')->generateJson();
        
        return $this->redirect($this->generateUrl('app_admin.port.list'));
    }

    /**
     * @Template()
     *
     * @param Request $request
     * @param Port $port
     * @return array
     */
    public function historyAction(Request $request, Port $port)
    {
        $em = $this->getDoctrine();
        $query = $em->getRepository('AppBundle:PortHistory')->getHistoryListQuery($port);

        $paginator = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query,
            $request->query->get('page', 1),
            20,
            array('defaultSortFieldName' => 'ph.createdAt', 'defaultSortDirection' => 'desc')
        );

        return array(
            'pagination' => $pagination
        );
    }

    /**
     * @Template()
     *
     * @param Request $request
     * @return array
     */
    public function removedListAction(Request $request)
    {
        $em = $this->getDoctrine();
        $query = $em->getRepository('AppBundle:Port')->getRemovedListQuery();

        $paginator = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query,
            $request->query->get('page', 1),
            20,
            array('defaultSortFieldName' => 'p.updatedAt', 'defaultSortDirection' => 'desc')
        );

        return array(
            'pagination' => $pagination
        );
    }

    /**
     * @param Port $oldPort
     * @param Port $port
     */
    private function savePortEditHistory(Port $oldPort, Port $port)
    {
        $isEdited = false;
        $portHistory = new PortHistory();

        if($oldPort->getName() != $port->getName()) {
            $portHistory->setName($port->getName());
            $isEdited = true;
        }

        if($oldPort->getCountry() != $port->getCountry()) {
            $portHistory->setCountry($port->getCountry());
            $isEdited = true;
        }

        if($isEdited) {
            $em = $this->getDoctrine()->getManager();
            $portHistory
                ->setUser($this->getUser())
                ->setPort($port);

            $em->persist($portHistory);
            $em->flush();
            
            $this->container->get('app.service.json')->generateJson();
        }
    }
}
