<?php

namespace App\Services\Moderation;

use App\Enums\ModerationRuleType;
use App\Models\ContentModerationRule;

class ModerationRuleRegistryService
{
    /**
     * @return array<int, string>
     */
    public function suspiciousKeywords(): array
    {
        return $this->mergeValues(
            (array) \app('config')->get('content_moderation.keywords.suspicious', []),
            $this->rulesByType(ModerationRuleType::SuspiciousKeyword)
        );
    }

    /**
     * @return array<int, string>
     */
    public function highRiskKeywords(): array
    {
        return $this->mergeValues(
            (array) \app('config')->get('content_moderation.keywords.high_risk', []),
            $this->rulesByType(ModerationRuleType::HighRiskKeyword)
        );
    }

    /**
     * @return array<int, array{pattern:string,weight:?int,id:int|null}>
     */
    public function regexRules(): array
    {
        return ContentModerationRule::query()
            ->where('enabled', true)
            ->where('type', ModerationRuleType::Regex->value)
            ->orderByDesc('id')
            ->get(['id', 'value', 'weight'])
            ->map(static fn (ContentModerationRule $rule): array => [
                'pattern' => (string) $rule->value,
                'weight' => $rule->weight,
                'id' => $rule->id,
            ])
            ->values()
            ->all();
    }

    /**
     * @return array<int, string>
     */
    private function rulesByType(ModerationRuleType $type): array
    {
        return ContentModerationRule::query()
            ->where('enabled', true)
            ->where('type', $type->value)
            ->orderByDesc('id')
            ->pluck('value')
            ->map(static fn (string $value): string => trim($value))
            ->filter()
            ->values()
            ->all();
    }

    /**
     * @param array<int, string> $configValues
     * @param array<int, string> $dbValues
     * @return array<int, string>
     */
    private function mergeValues(array $configValues, array $dbValues): array
    {
        return \collect(array_merge($configValues, $dbValues))
            ->map(static fn (string $value): string => trim($value))
            ->filter()
            ->unique(static fn (string $value): string => mb_strtolower($value))
            ->values()
            ->all();
    }
}