<?php
namespace AppBundle\Utils\Services;


use AppBundle\Entity\Ad;
use AppBundle\Entity\ProductAd;

class AdManager
{

    protected $em;
    protected $security;
    protected $slugService;
    protected $mail_manager;

    /**
     * AdManager constructor.
     * @param $em
     * @param $security
     */
    public function __construct($em, $security, $slugService, $mail_manager)
    {
        $this->em = $em;
        $this->security = $security;
        $this->slugService = $slugService;
        $this->mail_manager = $mail_manager;
    }

    /**
     * @param Ad $ad
     *
     * Launch the Ad validation process by calling the next two function
     */
    public function processAdValidation(Ad $ad)
    {
        $this->updateTokens($ad);
        $this->updateStatus($ad);
        $this->em->persist($ad);
        $this->em->flush();
    }

    /**
     * @param Ad $ad
     *
     * Update tokens according to an Ad state / dates
     * Consume or refund tokens
     */
    public function updateTokens(Ad $ad)
    {
        $user = $this->security->getToken()->getUser();
        $numberOfMonth = $ad->calcMonth();
        //Cas ou l'on doit recrediter un produit mois
        if ($numberOfMonth < 0) {
            for ($i = $numberOfMonth; $i < 0; $i++) {
                $productsAd = $ad->getProducts();
                foreach ($productsAd as $productAd) {
                    if ($productAd->getProduct()->getType() == "MONTH") {
                        $product = $productAd->getProduct();
                        $product->setStatus("AVAILABLE");
                        $this->em->remove($productAd);
                        $this->em->persist($product);
                        $this->em->flush();
                        break;
                    }
                }
            }
        } else {
            //Insertion d'une ligne pour un produit annonce
            if (!$ad->hasAd()) {
                $adProduct = $user->getAvailableTokens('ad');
                $ap = $adProduct{0};
                $productAd = new ProductAd($ap, $ad);
                $this->em->persist($productAd);
                $ap->setStatus('CONSUME');
                $this->em->persist($adProduct{0});
            }
            //Insertion d'une ligne par produit mois necessaire en fonction du nombre de mois demandé
            $monthProduct = $user->getAvailableTokens('month');
            for ($i = 1; $i <= $numberOfMonth; $i++) {
                $mp = $monthProduct{($i - 1)};
                $mp->setStatus('CONSUME');
                $productAd = new ProductAd($mp, $ad);
                $this->em->persist($mp);
                $this->em->persist($productAd);
            }
        }
    }

    /**
     * @param Ad $ad
     *
     * Update Ad status in order to re-publish the Ad
     */
    public function updateStatus(Ad $ad)
    {
        if ($ad->getStatus() != "PUBLISHED") {
            if ($ad->getStatus() == "CLOSED" || $ad->getStatus() == "EXPIRED") {
                $ad->setStatus('VALIDATED');
            } else {
                $ad->setStatus('TO_PUBLISH');
            }
        }
    }

    /**
     * @param Ad $ad
     *
     * Must be called when an Ad is updated
     * Manage tags, slug, location and alias
     */
    public function updateAd(Ad $ad)
    {

        if (!is_array($ad->getPublicTag())) {
            $publicTags = explode(',', $ad->getPublicTag());
            $ad->setPublicTag($publicTags);
        }

        if (!is_array($ad->getLocation())) {
            $location = json_decode($ad->getLocation(), true);
            $ad->setLocation($location);
        }

        if ($ad->getId() == null) {
            $this->em->persist($ad);
            $this->em->flush();
        }
        $alias = $this->slugService->slugify($ad->getId() . "-" . $ad->getTitle());
        $ad->setAlias($alias);

        $this->em->persist($ad);
        $this->em->flush();
    }

    /**
     * @param $output
     *
     * Check if an Ad must be published or unpublished according to today's date
     */
    public function publishAd($output)
    {
        $repo = $this->em->getRepository('AppBundle:Ad');
        $sendMail = $this->mail_manager;
        $ads = $repo->findByStatus(array('VALIDATED', 'PUBLISHED'), array('id' => 'DESC'));
        $today = new \DateTime('now');
        $output->writeln('<fg=green>' . $today->format('Y-m-d H:i:s') . '</>');
        $stringToday = $today->format('Y-m-d');
        foreach ($ads as $ad) {
            $user = $ad->getCreator();
            $stringPublishedAt = $ad->getPublishedAt()->format('Y-m-d');
            if ($ad->getUnpublishedAt() <= $today && $ad->getStatus() == 'PUBLISHED') {
                $ad->setStatus('EXPIRED');
                $output->writeln("<fg=yellow>Ad (" . $ad->getId() . ")</> passed to status <fg=red>(EXPIRED)</>");
                $subject = "Annonce dépubliée";
                $message = $sendMail->buildAdMessage($ad, $user, 'Votre annonce a expiré et ne sera plus visible à compter de cette date.');
                $sendMail->sendMail($subject, $message, $user, 'contact_default');
            } else if ($stringPublishedAt == $stringToday && $ad->getStatus() == 'VALIDATED') {
                $ad->setStatus('PUBLISHED');
                $output->writeln("<fg=yellow>Ad (" . $ad->getId() . ")</> passed to status <fg=green>(PUBLISHED)</>");
                $subject = "Annonce publié";
                $message = $sendMail->buildAdMessage($ad, $user, 'Votre annonce a bien été publiée et est maintenant visible sur talentstube.com.');
                $sendMail->sendMail($subject, $message, $user, 'contact_default');
            }
            $this->em->persist($ad);
        }
        $this->em->flush();
        $output->writeln('##########> You are terminated <###########');
    }
}