<?php

declare(strict_types=1);

namespace Ost\OstCapabilityDataExport\Service;

use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry;
use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition;
use Shopware\Core\Framework\DataAbstractionLayer\Field\AssociationField;
use Shopware\Core\Framework\DataAbstractionLayer\Field\Field;

final class EntityMetadataService
{
    public function __construct(private readonly DefinitionInstanceRegistry $definitionRegistry)
    {
    }

    /**
     * @return array<int, array{entity: string, label: string}>
     */
    public function listEntities(): array
    {
        $entries = [];

        foreach ($this->definitionRegistry->getDefinitions() as $definition) {
            if (!$definition instanceof EntityDefinition) {
                continue;
            }

            $entityName = $definition->getEntityName();
            $entries[] = [
                'entity' => $entityName,
                'label' => $entityName,
            ];
        }

        usort($entries, static fn (array $a, array $b): int => strcmp($a['entity'], $b['entity']));

        return $entries;
    }

    /**
     * @return string[]
     */
    public function listExportableFields(string $entityName): array
    {
        $definition = $this->definitionRegistry->getByEntityName($entityName);
        if (!$definition instanceof EntityDefinition) {
            throw new \InvalidArgumentException(sprintf('Unknown entity: %s', $entityName));
        }

        $fields = [];
        foreach ($definition->getFields() as $field) {
            if (!$field instanceof Field) {
                continue;
            }
            if (!$this->isExportable($field)) {
                continue;
            }

            $property = $field->getPropertyName();
            if ($property === '' || $property === 'extensions') {
                continue;
            }
            $fields[] = $property;
        }

        sort($fields);

        return array_values(array_unique($fields));
    }

    private function isExportable(Field $field): bool
    {
        if ($field instanceof AssociationField) {
            return false;
        }

        return true;
    }
}
