<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Validator\Constraints;

use CpCreation\VitiCore\Product\Model\ProductVariant;
use CpCreation\VitiCore\Product\ProductVariantSkuResolver;
use CpCreation\VitiCore\Product\Repository\ProductVariantRepository;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;

final class EffectiveSkuAvailableValidator extends ConstraintValidator
{
    public function __construct(
        private readonly ProductVariantSkuResolver $skuResolver,
        private readonly ProductVariantRepository $variantRepository,
    ) {}

    public function validate(mixed $value, Constraint $constraint): void
    {
        if (!$constraint instanceof EffectiveSkuAvailable) {
            throw new UnexpectedTypeException($constraint, EffectiveSkuAvailable::class);
        }

        if (null === $value) {
            return;
        }

        if (!$value instanceof ProductVariant) {
            throw new UnexpectedValueException($value, ProductVariant::class);
        }

        $effectiveSku = $this->skuResolver->resolve($value);
        if (null === $effectiveSku || !$this->variantRepository->effectiveSkuExistsForAnotherVariant($value, $effectiveSku)) {
            return;
        }

        $this->context
            ->buildViolation($constraint->message)
            ->setParameter('{{ sku }}', $effectiveSku)
            ->atPath('sku')
            ->addViolation();
    }
}
