<?php

namespace Lc\SovBundle\Component;

use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\SovBundle\Doctrine\Extension\BlameableInterface;
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface;
use Lc\SovBundle\Doctrine\Extension\SeoInterface;
use Lc\SovBundle\Doctrine\Extension\SortableInterface;
use Lc\SovBundle\Doctrine\Extension\TimestampableInterface;
use Lc\SovBundle\Event\EntityComponentEvent;
use Lc\SovBundle\Model\File\FileInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class EntityComponent
{
    protected EntityManagerInterface $entityManager;
    protected ParameterBagInterface $parameterBag;
    protected EventDispatcherInterface $eventDispatcher;

    public function __construct(
            EntityManagerInterface $entityManager,
            ParameterBagInterface $parameterBag,
            EventDispatcherInterface $eventDispatcher
    ) {
        $this->entityManager = $entityManager;
        $this->parameterBag = $parameterBag;
        $this->eventDispatcher = $eventDispatcher;
    }

    public function duplicateEntity($entity)
    {
        $newEntity = clone $entity;

        $classMetadata = $this->entityManager->getClassMetadata(get_class($newEntity));

        //Dupplication de l'image ou du fichier lier
        foreach ($classMetadata->getAssociationMappings() as $associationMapping){
            if(in_array(FileInterface::class, class_implements($associationMapping['targetEntity']))){
                $methodGet = 'get'.ucfirst($associationMapping['fieldName']);
                $methodSet = 'set'.ucfirst($associationMapping['fieldName']);
                if(method_exists($newEntity, $methodGet) && method_exists($newEntity, $methodSet)){
                    if(!is_null($newEntity->$methodGet())){
                        $newFile = clone $newEntity->$methodGet();
                        $newEntity->$methodSet($newFile);
                    }
                }
            }
        }


        if($newEntity instanceof DevAliasInterface){
            $newEntity->setDevAlias(null);
        }

        if($newEntity instanceof SeoInterface) {
            $newEntity->setOldUrls(array());
        }

        if($newEntity instanceof BlameableInterface) {
            $newEntity->setUpdatedBy(null);
            $newEntity->setCreatedBy(null);
        }

        if($newEntity instanceof TimestampableInterface) {
            $newEntity->setUpdatedAt(new \DateTime());
            $newEntity->setCreatedAt(new \DateTime());
        }

        $this->eventDispatcher->dispatch(new EntityComponentEvent($newEntity), EntityComponentEvent::DUPLICATE_EVENT);

        //Ne pas utiliser create ici! Sinon pour certaine entité comme ProductFamily on réajoute un orginProduct
        $this->entityManager->create($newEntity, false);

        return $newEntity;
    }

    public function duplicateEntityToOtherHub($entity, $hub)
    {
        $newEntity = $this->duplicateEntity($entity);

        if ($hub) {
            $newEntity->setMerchant($hub);
        }
        $this->entityManager->persist($newEntity);
        $this->entityManager->flush();

        return $newEntity;
    }

    public function duplicateImage($entity, $folder = false)
    {
        $basePath = $this->parameterBag->get('kernel.project_dir') . '/public/uploads/images/';

        if ($entity->getImage() && file_exists($basePath . $entity->getImage())) {
            $extension = strtolower(pathinfo($basePath . $entity->getImage(), PATHINFO_EXTENSION));

            if ($extension == "jpg" || $extension == "png" || $extension == "gif") {
                $newImage = md5(uniqid()) . '.' . $extension;
                if ($folder) {
                    $newImage = $folder . '/' . $newImage;
                }
                copy($basePath . $entity->getImage(), $basePath . $newImage);
                $entity->setImage($newImage);
            } else {
                $entity->setImage(null);
            }
        } else {
            $entity->setImage(null);
        }
        return $entity;
    }
}
