<?php

declare(strict_types=1);

return [
    // Uses same queue family as vision jobs by default; keeps embedding work async and non-blocking.
    'queue' => env('RECOMMENDATIONS_QUEUE', env('VISION_QUEUE', 'default')),

    // ─── Phase 1 "For You" feed scoring weights ───────────────────────────────
    // Influences the PHP reranking pass after Meilisearch candidate retrieval.
    // Tweak here without code changes.
    'weights' => [
        // Tag overlap score weight (0–1 normalized overlap fraction)
        'tag_overlap'        => (float) env('RECO_W_TAG_OVERLAP',        0.40),
        // Creator affinity score weight (1.0 if followed, 0 otherwise)
        'creator_affinity'   => (float) env('RECO_W_CREATOR_AFFINITY',   0.25),
        // Popularity boost (log-normalised views/downloads)
        'popularity'         => (float) env('RECO_W_POPULARITY',         0.20),
        // Freshness boost (exponential decay over 30 days)
        'freshness'          => (float) env('RECO_W_FRESHNESS',          0.15),
    ],

    // ─── User preference signal weights ──────────────────────────────────────
    // How much each user action contributes to building the reco profile.
    'signal_weights' => [
        'award'    => (float) env('RECO_SIG_AWARD',    5.0),
        'favorite' => (float) env('RECO_SIG_FAVORITE', 3.0),
        'reaction' => (float) env('RECO_SIG_REACTION', 2.0),
        'view'     => (float) env('RECO_SIG_VIEW',     1.0),
        'follow'   => (float) env('RECO_SIG_FOLLOW',   2.0),
    ],

    // ─── Candidate generation ──────────────────────────────────────────────────
    // How many Meilisearch candidates to fetch before PHP reranking.
    'candidate_pool_size' => (int) env('RECO_CANDIDATE_POOL', 200),

    // ─── Diversity controls ────────────────────────────────────────────────────
    // Maximum artworks per creator allowed in a single page of results.
    'max_per_creator'     => (int) env('RECO_MAX_PER_CREATOR', 3),
    // Minimum distinct tag count in first 20 feed results.
    'min_unique_tags'     => (int) env('RECO_MIN_UNIQUE_TAGS', 5),

    // ─── TTLs (seconds) ────────────────────────────────────────────────────────
    'ttl' => [
        // User reco profile cache (tag/creator affinity data)
        'user_reco_profile'   => (int) env('RECO_TTL_PROFILE',      6 * 3600),
        // For You paginated results cache
        'for_you_feed'        => (int) env('RECO_TTL_FOR_YOU',       5 * 60),
        // Similar artworks per artwork
        'similar_artworks'    => (int) env('RECO_TTL_SIMILAR',       30 * 60),
        // Suggested creators per user
        'creator_suggestions' => (int) env('RECO_TTL_CREATORS',      30 * 60),
        // Suggested tags per user
        'tag_suggestions'     => (int) env('RECO_TTL_TAGS',          60 * 60),
    ],

    // ─── Profile limits ────────────────────────────────────────────────────────
    'profile' => [
        'top_tags_limit'         => (int) env('RECO_PROFILE_TAGS',      20),
        'top_categories_limit'   => (int) env('RECO_PROFILE_CATS',       5),
        'strong_creators_limit'  => (int) env('RECO_PROFILE_CREATORS',  50),
    ],

    'embedding' => [
        'enabled' => env('RECOMMENDATIONS_EMBEDDING_ENABLED', true),
        'model' => env('RECOMMENDATIONS_EMBEDDING_MODEL', 'clip'),
        'model_version' => env('RECOMMENDATIONS_EMBEDDING_MODEL_VERSION', 'v1'),
        'algo_version' => env('RECOMMENDATIONS_ALGO_VERSION', 'clip-cosine-v1'),

        // Preferred CLIP endpoint for embeddings. The service also accepts an embedding payload from the analyze endpoint response.
        'endpoint' => env('CLIP_EMBED_ENDPOINT', '/embed'),
        'timeout_seconds' => (int) env('CLIP_EMBED_TIMEOUT_SECONDS', 8),
        'connect_timeout_seconds' => (int) env('CLIP_EMBED_CONNECT_TIMEOUT_SECONDS', 2),
        'retries' => (int) env('CLIP_EMBED_HTTP_RETRIES', 1),
        'retry_delay_ms' => (int) env('CLIP_EMBED_HTTP_RETRY_DELAY_MS', 200),

        // Guardrails for malformed service responses.
        'min_dim' => (int) env('RECOMMENDATIONS_MIN_DIM', 64),
        'max_dim' => (int) env('RECOMMENDATIONS_MAX_DIM', 4096),
    ],

    // Backfill chunk size for resumable queue fan-out.
    'backfill_batch_size' => (int) env('RECOMMENDATIONS_BACKFILL_BATCH', 200),

    // A/B support for recommendation ranking variants.
    'ab' => [
        'algo_versions' => array_values(array_filter(array_map(
            static fn (string $value): string => trim($value),
            explode(',', (string) env('RECOMMENDATIONS_AB_ALGO_VERSIONS', env('RECOMMENDATIONS_ALGO_VERSION', 'clip-cosine-v1')))
        ))),
    ],

    // ─── Similar Artworks (hybrid recommender) ─────────────────────────────────
    'similarity' => [
        'model_version' => env('SIMILARITY_MODEL_VERSION', 'sim_v1'),

        // Vector DB integration (behind feature flag)
        'vector_enabled' => (bool) env('SIMILARITY_VECTOR_ENABLED', false),
        'vector_adapter' => env('SIMILARITY_VECTOR_ADAPTER', 'pgvector'), // pgvector | pinecone

        // Hybrid blend weights (spec §5.4)
        'weights_with_vector' => [
            'visual'   => (float) env('SIM_W_VISUAL',   0.45),
            'tag'      => (float) env('SIM_W_TAG_VEC',  0.25),
            'behavior' => (float) env('SIM_W_BEH_VEC',  0.20),
            'category' => (float) env('SIM_W_CAT_VEC',  0.10),
        ],
        'weights_without_vector' => [
            'tag'      => (float) env('SIM_W_TAG',      0.55),
            'behavior' => (float) env('SIM_W_BEH',      0.35),
            'category' => (float) env('SIM_W_CAT',      0.10),
        ],

        // Diversity caps (spec §6)
        'max_per_author'      => (int) env('SIM_MAX_PER_AUTHOR', 2),
        'result_limit'        => (int) env('SIM_RESULT_LIMIT', 30),
        'candidate_pool'      => (int) env('SIM_CANDIDATE_POOL', 100),
        'min_categories_top12' => (int) env('SIM_MIN_CATS_TOP12', 2),

        // Behavior pair building
        'user_favourites_cap' => (int) env('SIM_USER_FAV_CAP', 50),

        // Cache TTL for precomputed lists (sec)
        'cache_ttl'           => (int) env('SIM_CACHE_TTL', 6 * 3600),

        // Pinecone adapter settings
        'pinecone' => [
            'api_key'    => env('PINECONE_API_KEY'),
            'index_host' => env('PINECONE_INDEX_HOST'),
            'index_name' => env('PINECONE_INDEX_NAME', 'skinbase-artworks'),
            'namespace'  => env('PINECONE_NAMESPACE', ''),
            'top_k'      => (int) env('PINECONE_TOP_K', 100),
        ],
    ],
];
