<?php

declare(strict_types=1);

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Commerce\Catalog;

use CpCreation\VitiCore\Commerce\Catalog\Configuration\CatalogIntegrationConfiguration;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;

final readonly class CatalogIdentity
{
    public function __construct(private CatalogIntegrationConfiguration $configuration) {}

    public function instanceId(): string
    {
        return $this->configuration->instanceId();
    }

    public function sellerId(): string
    {
        return $this->prefix() . '_seller';
    }

    public function productId(UuidInterface|string $id): string
    {
        return $this->prefix() . '_product_' . $this->compact($id);
    }

    public function variantId(UuidInterface|string $id): string
    {
        return $this->prefix() . '_variant_' . $this->compact($id);
    }

    public function optionId(UuidInterface|string $id): string
    {
        return $this->prefix() . '_option_' . $this->compact($id);
    }

    public function mediaId(UuidInterface|string $id): string
    {
        return $this->prefix() . '_media_' . $this->compact($id);
    }

    public function categoryId(UuidInterface|string $id): string
    {
        return $this->prefix() . '_category_' . $this->compact($id);
    }

    public function parseProductId(string $catalogId): ?UuidInterface
    {
        $pattern = '/^' . preg_quote($this->prefix(), '/') . '_product_([a-f0-9]{32})$/';
        if (1 !== preg_match($pattern, mb_strtolower($catalogId), $matches)) {
            return null;
        }

        return Uuid::fromString($this->expand($matches[1]));
    }

    private function prefix(): string
    {
        return 'vc_' . $this->compact($this->instanceId());
    }

    private function compact(UuidInterface|string $id): string
    {
        $value = $id instanceof UuidInterface ? $id->toString() : $id;
        if (!Uuid::isValid($value)) {
            throw new \InvalidArgumentException(\sprintf('"%s" is not a valid UUID.', $value));
        }

        return str_replace('-', '', mb_strtolower($value));
    }

    private function expand(string $compact): string
    {
        return \sprintf(
            '%s-%s-%s-%s-%s',
            mb_substr($compact, 0, 8),
            mb_substr($compact, 8, 4),
            mb_substr($compact, 12, 4),
            mb_substr($compact, 16, 4),
            mb_substr($compact, 20, 12),
        );
    }
}
