<?php
declare(strict_types=1);

namespace Autogedal\StockSourceRouter\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Serialize\Serializer\Json;

class RouterConfig
{
    private const CONFIG_PATH = 'autogedal_stock_source_router/rules/routing_rules';

    private ?array $rulesCache = null;
    private ?array $skuIndex   = null;

    public function __construct(
        private readonly ScopeConfigInterface $scopeConfig,
        private readonly Json $json
    ) {}

    /**
     * Returns the routing rule for a given SKU, or null if the SKU is not configured.
     *
     * @return array{primary_source: string, fallback_source: string|null}|null
     */
    public function getRuleForSku(string $sku): ?array
    {
        return $this->getSkuIndex()[$sku] ?? null;
    }

    private function getSkuIndex(): array
    {
        if ($this->skuIndex !== null) {
            return $this->skuIndex;
        }

        $this->skuIndex = [];
        foreach ($this->getRules() as $rule) {
            $mapped = [
                'primary_source'  => (string)($rule['primary_source'] ?? ''),
                'fallback_source' => ($rule['fallback_source'] ?? '') ?: null,
            ];
            $skus = array_filter(array_map('trim', explode(',', (string)($rule['skus'] ?? ''))));
            foreach ($skus as $s) {
                // First rule wins if a SKU appears in multiple rules
                $this->skuIndex[$s] ??= $mapped;
            }
        }

        return $this->skuIndex;
    }

    private function getRules(): array
    {
        if ($this->rulesCache !== null) {
            return $this->rulesCache;
        }

        $value = $this->scopeConfig->getValue(self::CONFIG_PATH);
        if (!$value) {
            return $this->rulesCache = [];
        }

        try {
            $decoded = $this->json->unserialize($value);
            $this->rulesCache = is_array($decoded) ? $decoded : [];
        } catch (\Exception) {
            $this->rulesCache = [];
        }

        return $this->rulesCache;
    }
}
