<?php

declare(strict_types=1);

namespace App\Framework\Search;

/**
 * Configuration for a search field
 */
final readonly class SearchFieldConfig
{
    public function __construct(
        public SearchFieldType $type,
        public bool $isSearchable = true,
        public bool $isFilterable = true,
        public bool $isSortable = true,
        public bool $isHighlightable = true,
        public float $boost = 1.0,
        public ?string $analyzer = null,
        public ?string $format = null,
        public array $options = []
    ) {
    }

    public function isText(): bool
    {
        return $this->type === SearchFieldType::TEXT;
    }

    public function isKeyword(): bool
    {
        return $this->type === SearchFieldType::KEYWORD;
    }

    public function isNumeric(): bool
    {
        return in_array($this->type, [
            SearchFieldType::INTEGER,
            SearchFieldType::FLOAT,
            SearchFieldType::DOUBLE,
        ]);
    }

    public function isDate(): bool
    {
        return $this->type === SearchFieldType::DATE;
    }

    public function isBoosted(): bool
    {
        return $this->boost !== 1.0;
    }

    public function withBoost(float $boost): self
    {
        return new self(
            $this->type,
            $this->isSearchable,
            $this->isFilterable,
            $this->isSortable,
            $this->isHighlightable,
            $boost,
            $this->analyzer,
            $this->format,
            $this->options
        );
    }

    public function withAnalyzer(string $analyzer): self
    {
        return new self(
            $this->type,
            $this->isSearchable,
            $this->isFilterable,
            $this->isSortable,
            $this->isHighlightable,
            $this->boost,
            $analyzer,
            $this->format,
            $this->options
        );
    }

    public function searchableOnly(): self
    {
        return new self(
            $this->type,
            true,
            false,
            false,
            $this->isHighlightable,
            $this->boost,
            $this->analyzer,
            $this->format,
            $this->options
        );
    }

    public function filterableOnly(): self
    {
        return new self(
            $this->type,
            false,
            true,
            $this->isSortable,
            false,
            $this->boost,
            $this->analyzer,
            $this->format,
            $this->options
        );
    }

    public static function text(float $boost = 1.0, ?string $analyzer = null): self
    {
        return new self(
            type: SearchFieldType::TEXT,
            boost: $boost,
            analyzer: $analyzer
        );
    }

    public static function keyword(bool $sortable = true): self
    {
        return new self(
            type: SearchFieldType::KEYWORD,
            isSortable: $sortable,
            isHighlightable: false
        );
    }

    public static function integer(bool $sortable = true): self
    {
        return new self(
            type: SearchFieldType::INTEGER,
            isSearchable: false,
            isSortable: $sortable,
            isHighlightable: false
        );
    }

    public static function float(bool $sortable = true): self
    {
        return new self(
            type: SearchFieldType::FLOAT,
            isSearchable: false,
            isSortable: $sortable,
            isHighlightable: false
        );
    }

    public static function date(bool $sortable = true, ?string $format = null): self
    {
        return new self(
            type: SearchFieldType::DATE,
            isSearchable: false,
            isSortable: $sortable,
            isHighlightable: false,
            format: $format
        );
    }

    public static function boolean(): self
    {
        return new self(
            type: SearchFieldType::BOOLEAN,
            isSearchable: false,
            isSortable: false,
            isHighlightable: false
        );
    }

    public function toArray(): array
    {
        return [
            'type' => $this->type->value,
            'is_searchable' => $this->isSearchable,
            'is_filterable' => $this->isFilterable,
            'is_sortable' => $this->isSortable,
            'is_highlightable' => $this->isHighlightable,
            'boost' => $this->boost,
            'analyzer' => $this->analyzer,
            'format' => $this->format,
            'options' => $this->options,
        ];
    }
}
