<?php

namespace PlanificationLivraison\EventListeners;

use DateTime;
use LivraisonParSecteurs\LivraisonParSecteurs;
use LivraisonParSecteurs\Model\LpsAreaScheduleQuery;
use PlanificationLivraison\Model\OrderDeliverySchedule;
use PlanificationLivraison\PlanificationLivraison;
use Propel\Runtime\Propel;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Thelia\Action\BaseAction;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Exception\TheliaProcessException;
use Thelia\Files\Exception\ProcessFileException;


class DeliveryListener extends BaseAction implements EventSubscriberInterface
{
    /** @var RequestStack */
    protected $requestStack;

    /**
     * DeliveryPostageListener constructor.
     * @param RequestStack $requestStack
     */
    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }


    /**
     * @param OrderEvent $event
     * @throws \Propel\Runtime\Exception\PropelException
     */
    public function recordCurrentDeliveryAddress(OrderEvent $event, $eventName, EventDispatcherInterface $dispatcher)
    {
        /** @var Request $request */
        $request = $this->requestStack->getCurrentRequest();

        /** @var Session $session */
        $session = $request->getSession();

        if ($event->getDeliveryModule() == LivraisonParSecteurs::getModuleId()) {
            if (null !== $scheduleId = $request->get('lps-choosen-day', null)) {
                $session->set(LivraisonParSecteurs::LPS_AREA_SCHEDULE_ID, $scheduleId);
                $session->set(LivraisonParSecteurs::LPS_CHOSEN_ADDRESS, $session->getOrder()->getChoosenDeliveryAddress());

                $scheduleId = $session->get(LivraisonParSecteurs::LPS_AREA_SCHEDULE_ID);
                $schedule = LpsAreaScheduleQuery::create()->findOneById($scheduleId);

                $chosenDate = LivraisonParSecteurs::calculateRelativeDate($schedule->getDay());

                // On sauvegarde la date de livraison choisie avec les heures, pour affichage ultérieur.
                $completeDay = LivraisonParSecteurs::getDayLabel($schedule->getDay());
                $completeDay .= " " . $chosenDate->format(LivraisonParSecteurs::FORMAT_DATES);
                $session->set(LivraisonParSecteurs::LPS_DELIVERY_DATE, $completeDay);
                $session->set(LivraisonParSecteurs::LPS_DELIVERY_BEGIN_TIME, $schedule->getBeginTime());
                $session->set(LivraisonParSecteurs::LPS_DELIVERY_END_TIME, $schedule->getEndTime());
            }
        }
    }

    /**
     * @param OrderEvent $event
     * @throws \Propel\Runtime\Exception\PropelException
     */
    public function updateCurrentDeliveryAddress(OrderEvent $event)
    {
        /** @var Session $session */
        $session = $this->requestStack->getCurrentRequest()->getSession();

        $order = $event->getOrder();

        $deliveryModuleId = $order->getDeliveryModuleId();
        if ($deliveryModuleId == LivraisonParSecteurs::getModuleId()) {
            $scheduleId = $session->get(LivraisonParSecteurs::LPS_AREA_SCHEDULE_ID);
            $orderId = $order->getId();

            $con = Propel::getConnection();
            $con->beginTransaction();
            $query = new OrderDeliverySchedule();
            try {
                $query->setOrderId($orderId);
                $query->setScheduleId($scheduleId);
                $query->setDeliveryAddressId($session->get(LivraisonParSecteurs::LPS_CHOSEN_ADDRESS));

                $schedule = LpsAreaScheduleQuery::create()->findOneById($scheduleId);
                $chosenDate = LivraisonParSecteurs::calculateRelativeDate($schedule->getDay());

                $format = LivraisonParSecteurs::FORMAT_DATE_COMPLETE;
                $startDate = DateTime::createFromFormat($format, $chosenDate->format('Y-m-d ') . $schedule->getBeginTime()->format('H:i:s'));
                $query->setDueDeliveryTimeStart($startDate);
                $endDate = DateTime::createFromFormat($format, $chosenDate->format('Y-m-d ') . $schedule->getEndTime()->format('H:i:s'));
                $query->setDueDeliveryTimeEnd($endDate);

                $query->save($con);
                $con->commit();
            }
            catch (\Exception $e) {
                throw new TheliaProcessException("PlanificationLivraison : Impossible to record this schedule - Cause : " . $e->getMessage());
            }
        }
    }


    public static function getSubscribedEvents()
    {
        return [
            TheliaEvents::ORDER_SET_DELIVERY_MODULE => ['recordCurrentDeliveryAddress', 64],
            TheliaEvents::ORDER_BEFORE_PAYMENT => ['updateCurrentDeliveryAddress', 64]
        ];
    }
}
