<?php

namespace AutoAdmin\Bundle\Content\Duplicator\Service;

use AutoAdmin\Bundle\Content\Duplicator\Enum\StringDuplicateModeEnum;

class StringDuplicator
{
    protected const LABEL_DUPLICATE_MARKER = ' (dup)';
    protected const NOSEP_SLUG_MARKER = 'dup';
    protected const KEBAB_SLUG_DUPLICATE_MARKER = '-'.self::NOSEP_SLUG_MARKER;
    protected const SNAKE_SLUG_DUPLICATE_MARKER = '_'.self::NOSEP_SLUG_MARKER;

    public function getLabelMarker(): string
    {
        return self::LABEL_DUPLICATE_MARKER;
    }

    public function getNoSepSlugMarker(): string
    {
        return self::NOSEP_SLUG_MARKER;
    }

    public function getKebabSlugMarker(): string
    {
        return self::KEBAB_SLUG_DUPLICATE_MARKER;
    }

    public function getSnakeSlugMarker(): string
    {
        return self::SNAKE_SLUG_DUPLICATE_MARKER;
    }

    public function duplicate(string $string, StringDuplicateModeEnum $mode): string
    {
        if ($mode == StringDuplicateModeEnum::KEBAB) {
            preg_match('/(.+)(\-'.self::NOSEP_SLUG_MARKER.'\-[a-zA-Z0-9]{3})/', $string, $matches);
        } elseif ($mode == StringDuplicateModeEnum::SNAKE) {
            preg_match('/(.+)(\_'.self::NOSEP_SLUG_MARKER.'\_[a-zA-Z0-9]{3})/', $string, $matches);
        } elseif ($mode == StringDuplicateModeEnum::LABEL) {
            preg_match('/(.+)(\ \('.self::NOSEP_SLUG_MARKER.'\))/', $string, $matches);
        } else {
            throw new \InvalidArgumentException(sprintf('Mode "%s" is not supported', $mode->value));
        }

        $separator = $this->getSeparator($mode);
        $dupId = substr(sha1(uniqid()), 0, 3);
        if ($mode == StringDuplicateModeEnum::LABEL) {
            $suffix = $separator.'(dup)';
        } else {
            $suffix = $separator.'dup'.$separator.$dupId;
        }

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

        return $string.$suffix;
    }

    public function getSeparator(StringDuplicateModeEnum $mode): string
    {
        return match ($mode) {
            StringDuplicateModeEnum::KEBAB => '-',
            StringDuplicateModeEnum::SNAKE => '_',
            StringDuplicateModeEnum::LABEL => ' ',
        };
    }
}
