<?php

declare(strict_types=1);

namespace NoahVet\Reef\Traits\DataFixtures;

trait BaseFixturesTrait
{
    /**
     * @template T of object
     *
     * @param array<string, mixed>           $data
     * @param array<string, class-string<T>> $dependencies
     */
    protected function resolveReferences(
        array &$data,
        array $dependencies,
    ): void {
        foreach ($dependencies as $name => $entityFQCN) {
            $this->resolveReference(
                $data,
                $name,
                $entityFQCN,
            );
        }
    }

    /**
     * @template T of object
     *
     * @param array<string, mixed>           $data
     * @param array<string, class-string<T>> $dependencies
     */
    protected function resolveIds(
        array &$data,
        array $dependencies,
    ): void {
        foreach ($dependencies as $name => $entityFQCN) {
            $this->resolveId(
                $data,
                $name,
            );
        }
    }

    /**
     * @template T of object
     *
     * @param array<string, mixed> $data
     * @param class-string<T>      $entityFQCN
     */
    protected function resolveReference(
        array &$data,
        string $name,
        string $entityFQCN,
    ): void {
        if (\is_array($data[$name]) && isset($data[$name]['ref'])) {
            $data[$name] = $this->getReference(
                $data[$name]['ref'],
                $entityFQCN,
            );
        }
    }

    /**
     * @param array<string, mixed> $data
     * @param array<string, mixed> $dependencies
     */
    protected function resolveDependencies(
        array &$data,
        array $dependencies,
    ): void {
        $this->resolveIds(
            $data,
            $dependencies,
        );

        $this->resolveReferences(
            $data,
            $dependencies,
        );
    }

    /**
     * @param array<string, mixed> $data
     */
    protected function resolveId(
        array &$data,
        string $name,
    ): void {
        $repositoryName = $name.'Repository';
        if (\is_array($data[$name]) && isset($data[$name]['id'])) {
            $data[$name] = $this->{$repositoryName}->find(
                $data[$name]['id'],
            );
        }
    }
}
