<?php

namespace App\Services\Moderation;

use App\Enums\ModerationStatus;
use App\Models\ContentModerationFinding;
use App\Models\User;

class UserModerationProfileService
{
    /**
     * @return array<string, mixed>|null
     */
    public function profile(?int $userId): ?array
    {
        if (! $userId) {
            return null;
        }

        $user = User::query()->with('statistics:user_id,uploads_count')->find($userId);
        if (! $user) {
            return null;
        }

        $findings = ContentModerationFinding::query()->where('user_id', $userId)->get([
            'id', 'status', 'is_auto_hidden', 'is_false_positive', 'matched_domains_json', 'campaign_key', 'priority_score', 'created_at',
        ]);

        $confirmedSpam = $findings->where('status', ModerationStatus::ConfirmedSpam)->count();
        $safeCount = $findings->where('status', ModerationStatus::ReviewedSafe)->count();
        $autoHidden = $findings->where('is_auto_hidden', true)->count();
        $falsePositives = $findings->where('is_false_positive', true)->count();
        $clusters = $findings->pluck('campaign_key')->filter()->unique()->count();
        $domains = $findings->flatMap(static fn (ContentModerationFinding $finding): array => (array) $finding->matched_domains_json)->filter()->unique()->values();
        $risk = app(UserRiskScoreService::class)->assess($userId, $domains->all());

        $tier = match (true) {
            $risk['risk_score'] >= 75 => 'high_risk',
            $risk['risk_score'] >= 45 => 'monitored',
            $risk['risk_score'] <= 8 && $safeCount >= 2 => 'trusted',
            default => 'normal',
        };

        $recommendedPolicy = match ($tier) {
            'high_risk' => 'new_user_strict_mode',
            'monitored' => 'comments_high_volume_antispam',
            'trusted' => 'trusted_user_relaxed_mode',
            default => 'default',
        };

        return [
            'user' => $user,
            'risk_score' => $risk['risk_score'],
            'trust_score' => max(0, 100 - $risk['risk_score'] + ($safeCount * 3) - ($falsePositives * 2)),
            'tier' => $tier,
            'recommended_policy' => $recommendedPolicy,
            'confirmed_spam_count' => $confirmedSpam,
            'safe_count' => $safeCount,
            'auto_hidden_count' => $autoHidden,
            'false_positive_count' => $falsePositives,
            'cluster_memberships' => $clusters,
            'promoted_domains' => $domains->take(12)->all(),
            'signals' => $risk['signals'],
        ];
    }
}