<?php

declare(strict_types=1);

namespace App\Framework\Search;

/**
 * Configuration for a search index
 */
final readonly class SearchIndexConfig
{
    /**
     * @param array<string, SearchFieldConfig> $fields
     * @param array<string, mixed> $settings
     */
    public function __construct(
        public string $entityType,
        public array $fields,
        public array $settings = [],
        public bool $enabled = true
    ) {
    }

    public function hasField(string $fieldName): bool
    {
        return isset($this->fields[$fieldName]);
    }

    public function getField(string $fieldName): ?SearchFieldConfig
    {
        return $this->fields[$fieldName] ?? null;
    }

    public function getSearchableFields(): array
    {
        return array_filter(
            $this->fields,
            fn ($field) => $field->isSearchable
        );
    }

    public function getFilterableFields(): array
    {
        return array_filter(
            $this->fields,
            fn ($field) => $field->isFilterable
        );
    }

    public function getSortableFields(): array
    {
        return array_filter(
            $this->fields,
            fn ($field) => $field->isSortable
        );
    }

    public function withField(string $name, SearchFieldConfig $field): self
    {
        $fields = $this->fields;
        $fields[$name] = $field;

        return new self(
            $this->entityType,
            $fields,
            $this->settings,
            $this->enabled
        );
    }

    public function withSetting(string $key, mixed $value): self
    {
        $settings = $this->settings;
        $settings[$key] = $value;

        return new self(
            $this->entityType,
            $this->fields,
            $settings,
            $this->enabled
        );
    }

    public function toArray(): array
    {
        return [
            'entity_type' => $this->entityType,
            'fields' => array_map(fn ($field) => $field->toArray(), $this->fields),
            'settings' => $this->settings,
            'enabled' => $this->enabled,
        ];
    }
}
