<?php

declare(strict_types=1);

/**
 * Ranking system configuration — Skinbase rank_v1
 *
 * All weights, half-lives, and thresholds are tunable here.
 * Increment model_version when changing weights so caches expire gracefully.
 */
return [

    // ── Model versioning ────────────────────────────────────────────────────
    'model_version' => 'rank_v2',

    // ── Engagement signal weights (log-scaled) ──────────────────────────────
    'weights' => [
        'views'      => 1.0,
        'favourites' => 3.0,
        'downloads'  => 2.5,
    ],

    // ── V2 ranking formula weights ──────────────────────────────────────────
    'v2' => [
        // Base engagement weights (linear, applied to raw counts)
        'weights' => [
            'views'      => 0.2,
            'downloads'  => 1.5,
            'favourites' => 2.5,
            'comments'   => 3.0,
            'shares'     => 4.0,   // highest — viral intent
        ],

        // 24h velocity weights
        'velocity_weights' => [
            'views'      => 1.0,
            'favourites' => 3.0,
            'comments'   => 4.0,
            'shares'     => 5.0,
        ],

        // Velocity multiplier applied to the 24h velocity sum
        'velocity_multiplier' => 0.5,

        // Recency decay half-life in hours
        'half_life' => 48,

        // Author authority: multiplier = 1 + (authority * factor)
        'authority_factor'      => 0.05,
        'authority_fav_divisor' => 1000,
    ],

    // ── Time-decay half-lives (hours) ───────────────────────────────────────
    'half_life' => [
        'trending'  => 72,   // Explore / global trending
        'new_hot'   => 36,   // New & Hot novelty feed
        'best'      => 720,  // Evergreen / Best-of (30 days)
        'category'  => 96,   // Per-category trending
    ],

    // ── Novelty boost (New & Hot only) ──────────────────────────────────────
    'novelty_weight' => 0.35,

    // ── Quality modifiers ───────────────────────────────────────────────────
    'quality' => [
        'has_tags'       => 0.05,
        'has_thumbnail'  => 0.02,
        'tag_count_max'  => 10,
        'tag_count_bonus' => 0.01,  // per normalised tag fraction (max 0.01 total)
        'penalty_hidden' => 0.50,   // deducted if hidden/inactive
    ],

    // ── Diversity constraints ────────────────────────────────────────────────
    'diversity' => [
        'max_per_author' => 3,
        'list_size'      => 50,
        'candidate_pool' => 200,  // top N candidates to run diversity filter on
    ],

    // ── Anti-spam / burst-view damping ──────────────────────────────────────
    'spam' => [
        'views_24h_threshold'     => 2000,
        'fav_ratio_threshold'     => 0.002,
        'dl_ratio_threshold'      => 0.001,
        'trending_penalty_factor' => 0.5,
    ],

    // ── Redis cache ─────────────────────────────────────────────────────────
    'cache' => [
        'ttl'     => 900,     // seconds (15 min) — lists are rebuilt hourly
        'prefix'  => 'rank',
    ],
];
