<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use AppBundle\Enum\ModulePosition;
use AppBundle\Enum\ModuleType as ModuleTypeEnum;
use AppBundle\Helper\ModuleHelper;
use Cocur\Slugify\Slugify;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Module
 *
 * @ORM\Table(name="module")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ModuleRepository")
 */
class Module
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var int
     *
     * @ORM\Column(name="menu", type="integer")
     */
    /**
     * @var integer $menu
     *
     * @ORM\ManyToMany(targetEntity="Menu")
     * @ORM\JoinColumn(name="menu", referencedColumnName="id", nullable=true)
     */
    private $menu;

    /**
     * @var string
     *
     * @ORM\Column(name="position", type="string", length=255, nullable=true)
     */
    private $position;

    /**
     * @var string
     *
     * @ORM\Column(name="type", type="string", length=255)
     */
    private $type;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255)
     */
    private $title;

    /**
     * @var \String
     *
     * @ORM\Column(name="picture", type="string", length=255, nullable=true)
     */
    private $picture;

    /**
     * @var \stdClass
     *
     * @ORM\Column(name="params", type="object")
     */
    private $params;

    /**
     * @var \string
     *
     * @ORM\Column(name="layout", type="string", length=255)
     */
    private $layout = 'default.html.twig';

    /**
     * @var \string
     *
     * @ORM\Column(name="custom_class", type="string", length=255, nullable=true)
     */
    private $customClass;

    /**
     * @var \integer
     *
     * @ORM\Column(name="ordering", type="integer", nullable=false)
     */
    private $ordering = 0;

    /**
     * @var bool
     *
     * @ORM\Column(name="is_active", type="boolean", nullable=false)
     */
    private $isActive = true;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created", type="datetime")
     */
    private $created;

    /**
     * @var \DateTime|null
     *
     * @ORM\Column(name="updated", type="datetime", nullable=true)
     */
    private $updated;


    private $formClass;


    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set menu.
     *
     * @param int $menu
     *
     * @return Module
     */
    public function setMenu($menu)
    {
        $this->menu = $menu;

        return $this;
    }

    /**
     * Get menu.
     *
     * @return int
     */
    public function getMenu()
    {
        return $this->menu;
    }

    /**
     * Set position.
     *
     * @param int $position
     *
     * @return Module
     */
    public function setPosition($position)
    {
        $this->position = $position;

        return $this;
    }

    /**
     * Get position.
     *
     * @return int
     */
    public function getPosition()
    {
        return $this->position;
    }

    /**
     * Set type.
     *
     * @param string $type
     *
     * @return Module
     */
    public function setType($type)
    {
        $this->type = $type;

        $this->setFormClass($type); 

        return $this;
    }

    /**
     * Get type.
     *
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Set picture.
     *
     * @param string $picture
     *
     * @return Module
     */
    public function setPicture($picture)
    {        
        if (null === $picture) {
            $this->tempPicture = $this->getAbsolutePicture();
        }
        
        $this->picture = $picture;

        return $this;
    }

    /**
     * Get picture.
     *
     * @return string
     */
    public function getPicture()
    {
        return $this->picture;
    }

    /**
     * Set title.
     *
     * @param string $title
     *
     * @return Module
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

    /**
     * Get title.
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * Set params.
     *
     * @param \stdClass $params
     *
     * @return Module
     */
    public function setParams($params)
    {
        if (isset($params->picture)) {
            unset($params->picture); 
        }
        
        $this->params = $params;

        return $this;
    }

    /**
     * Get params.
     *
     * @return \stdClass
     */
    public function getParams()
    {
        return $this->params;
    }

    /**
     * Set Layout.
     *
     * @param string $layout
     *
     * @return Module
     */
    public function setLayout($layout)
    {
        $this->layout = $layout;

        return $this;
    }

    /**
     * Get layout.
     *
     * @return string
     */
    public function getLayout()
    {
        return $this->layout;
    }

    /**
     * Get layout path.
     *
     * @return string
     */
    public function getLayoutPath()
    {
        if (!empty($this->formClass)) {
            $layoutPath = 'Front/Render/Module/'.$this->formClass;
            
            $list = $this->getLayoutList();
            
            if (in_array($this->layout, $list)) {
                return $layoutPath.'/'.$this->layout;
            }

            return $layoutPath.'/default.html.twig';
        }

        return null;
    }

    /**
     * Set custom class.
     *
     * @param bool $customClass
     *
     * @return Module
     */
    public function setCustomClass($customClass)
    {
        $this->customClass = $customClass;

        return $this;
    }

    /**
     * Get custom class.
     *
     * @return bool
     */
    public function getCustomClass()
    {
        return $this->customClass;
    }

    /**
     * Set ordering.
     *
     * @param bool $ordering
     *
     * @return Module
     */
    public function setOrdering($ordering)
    {
        $this->ordering = $ordering;

        return $this;
    }

    /**
     * Get ordering.
     *
     * @return bool
     */
    public function getOrdering()
    {
        return $this->ordering;
    }

    /**
     * Set isActive.
     *
     * @param bool $isActive
     *
     * @return Module
     */
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;

        return $this;
    }

    /**
     * Get isActive.
     *
     * @return bool
     */
    public function getIsActive()
    {
        return $this->isActive;
    }

    /**
     * Set created.
     *
     * @param \DateTime $created
     *
     * @return Module
     */
    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    /**
     * Get created.
     *
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }

    /**
     * Set updated.
     *
     * @param \DateTime|null $updated
     *
     * @return Module
     */
    public function setUpdated($updated = null)
    {
        $this->updated = $updated;

        return $this;
    }

    /**
     * Get updated.
     *
     * @return \DateTime|null
     */
    public function getUpdated()
    {
        return $this->updated;
    }

    /**
     * Set form Class.
     *
     * @param string $type
     *
     * @return Module
     */
    public function setFormClass($type)
    {        
        $this->formClass = str_replace('_', '', ucwords($type, "_"));

        return $this;
    }

    /**
     * Get form class.
     *
     * @return \String|null
     */
    public function getFormClass()
    {
        return $this->formClass;
    }

    /**
     * Get layout list
     *
     * @return Array
     */
    public function getLayoutList()
    {        
        if (!empty($this->formClass)) {
            $srcDir = __DIR__.'/../../../app/';
            $layoutPath = $srcDir.'Resources/views/Front/Render/Module/'.$this->formClass;
            
            if (is_dir($layoutPath)) {
                $list = array_values(array_diff(scandir($layoutPath), array('..', '.')));
                // Exclude file beginning by _
                foreach ($list as $i => $file) {
                    if (preg_match('/^_/', $file)) {
                        unset($list[$i]);
                    }
                }
                return array_combine($list, $list);
            }
        }

        return array('default.html.twig' => 'default.html.twig');
    }

    /**
     * Get Position list
     *
     * @return Array
     */
    public function getPositionList()
    {        
        return ModuleHelper::getPositionList();
    }



    /****
     * 
     * FILE UPLOAD
     * 
     *****/

    private $tempPicture;

     /**
     * @Assert\Image(
     *      maxWidth = 2000,
     *      maxWidthMessage = "Lʼimage ne doit pas dépasser 2000 pixels de large",
     *      maxHeight = 1000,
     *      maxHeightMessage = "Lʼimage ne doit pas dépasser 1000 pixels de haut",
     *      maxSizeMessage = "Lʼimage ne doit pas dépasser 5Mb.",
     *      maxSize = "6000000",
     *      mimeTypes = {"image/jpg", "image/jpeg", "image/gif", "image/png"},
     *      mimeTypesMessage = "Les images doivent être au format JPG, GIF ou PNG."
     * )
     */
    private $filePicture;

    /**
     * Sets file.
     *
     * @param UploadedFile $filePicture
     */
    public function setFilePicture(UploadedFile $filePicture = null)
    {
        $this->filePicture = $filePicture;

        // check if we have an old image path
        if (is_file($this->getAbsolutePicture())) {
            // store the old name to delete after the update
            $this->tempPicture = $this->getAbsolutePicture();
        }
    }

     /**
     * Get UploadedFile Picture
     *
     * @return UploadedFile
     */
    public function getFilePicture()
    {
        return $this->filePicture;   
    }

    public function getAbsolutePicture()
    {
        return  null === $this->picture
                ? null
                : $this->getUploadRootDir() . DIRECTORY_SEPARATOR . $this->picture;
    }

    public function getWebPicture()
    {
        return null === $this->picture
                ? null
                : $this->getUploadDir() . DIRECTORY_SEPARATOR . $this->picture;
    }

    protected function getUploadRootDir()
    {
        // the absolute directory path where uploaded
        // documents should be saved
        return __DIR__
            . DIRECTORY_SEPARATOR
            . join(DIRECTORY_SEPARATOR, ['..', '..', '..', 'web'])
            . DIRECTORY_SEPARATOR
            . $this->getUploadDir()
        ;
    }

    protected function getUploadDir()
    {
        // get rid of the __DIR__ so it doesn't screw up
        // when displaying uploaded doc/image in the view.
        return join(DIRECTORY_SEPARATOR, ['uploads', 'module']);
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUploadFilePicture()
    {   
        $uniqueIdentifier = sha1(uniqid(mt_rand(), true));
        $slugify = new Slugify();

        if (null !== $this->getFilePicture()) {
            $filenameWithoutExtension = substr($this->getFilePicture()->getClientOriginalName(), 0, -1 * (strlen($this->getFilePicture()->getClientOriginalExtension()) + 1));

            $this->picture = $uniqueIdentifier . '-' . $slugify->slugify($filenameWithoutExtension) . '.' . $this->getFilePicture()->getClientOriginalExtension();
        }
    }

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function uploadFilePicture()
    {
        if (null === $this->getFilePicture()) {
            return;
        }

        //Delete old file
        if (isset($this->tempPicture)) {
            if (is_file($this->tempPicture)) {
                unlink($this->tempPicture);
            }
        }

        //Move new file
        if (isset($this->picture) && is_string($this->picture)) {
            $this->getFilePicture()->move(
                $this->getUploadRootDir(),
                $this->picture
            );
        }

        $this->setFilePicture(null);
    }

    /**
     * @ORM\PreRemove()
     */
    public function storeFilenameForRemove()
    {
        $this->tempPicture = $this->getAbsolutePicture();
    }

    /**
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        if (isset($this->tempPicture) && is_file($this->tempPicture)) {
            unlink($this->tempPicture);
        }
    }
}
