<?php

namespace AutoAdmin\Bundle\Content\Duplicator;

use AutoAdmin\Bundle\BrickBuilder\Builder\BuilderService;
use AutoAdmin\Bundle\Content\Service\DuplicatorService;
use Doctrine\ORM\EntityManagerInterface;
use ReflectionClass;

abstract class AbstractDuplicator implements DuplicatorInterface
{
    protected DuplicatorService $duplicatorService;
    protected BuilderService $builderService;
    protected EntityManagerInterface $entityManager;

    public function __construct(
        DuplicatorService $duplicatorService,
        BuilderService $builderService,
        EntityManagerInterface $entityManager
    ) {
        $this->duplicatorService = $duplicatorService;
        $this->builderService = $builderService;
        $this->entityManager = $entityManager;
    }

    public function isSupported(object $entity): bool
    {
        $reflection = new ReflectionClass($entity);

        $interfacesDiff = array_intersect($reflection->getInterfaceNames(), $this->supportInterfaces());
        $attributeProps = $this->getPropertiesWithAttributes($entity, $this->supportAttributes());

        return !empty($interfacesDiff) || !empty($attributeProps);
    }

    public function supportInterfaces(): array
    {
        return [
            // replace with interfaces if needed
//            SequencedInterface::class
        ];
    }

    public function supportAttributes(): array
    {
        return [
            // replace with attributes if needed
//            BrickBuilder::class
        ];
    }

    protected function getPropertiesWithAttribute(mixed $entity, string $attributeClassName): array
    {
        $reflection = new ReflectionClass($entity);
        $matching = [];

        foreach ($reflection->getProperties() as $property) {
            foreach ($property->getAttributes() as $attribute) {
                if ($attribute->getName() === $attributeClassName) {
                    $matching[] = $property;
                }
            }
        }

        return $matching;
    }

    protected function getPropertiesWithAttributes(mixed $entity, array $attributes): array
    {
        $matching = [];

        foreach ($attributes as $attribute) {
            $matching = [...$matching, ...$this->getPropertiesWithAttribute($entity, $attribute)];
        }

        return $matching;
    }

    protected function appendSlugSuffix(string $slug): string
    {
        preg_match('/(.+)(\-dup\-[a-zA-Z0-9]{3})/', $slug, $matches);

        // if already duplicated, replace suffix
        if (!empty($matches) && !empty($suffix = $matches[2])) {
            $slug = substr($slug, 0, -1 * strlen($suffix));
        }

        return $slug.'-dup-'.substr(sha1(uniqid()), 0, 3);
    }
}
