use std::time::Duration;

use tidaldb::schema::{DecaySpec, EntityKind, SchemaBuilder, TextFieldType, Window};

/// Default embedding dimension used when no embedder sidecar is configured.
/// 8-dimensional category-axis space (P0/P1 behaviour).
pub const DEFAULT_DIM: usize = 8;

/// Embedding dimension when a real embedding sidecar is in use
/// (OpenAI text-embedding-3-small outputs 1536 dimensions).
pub const REAL_DIM: usize = 1536;

pub fn build(embedding_dim: usize) -> tidaldb::schema::Schema {
    let mut b = SchemaBuilder::new();

    let _ = b
        .signal(
            "view",
            EntityKind::Item,
            DecaySpec::Exponential {
                half_life: Duration::from_secs(7 * 86_400),
            },
        )
        .windows(&[Window::TwentyFourHours, Window::AllTime])
        .velocity(true)
        .add();

    let _ = b
        .signal(
            "dwell",
            EntityKind::Item,
            DecaySpec::Exponential {
                half_life: Duration::from_secs(3 * 86_400),
            },
        )
        .windows(&[Window::TwentyFourHours, Window::AllTime])
        .velocity(false)
        .add();

    let _ = b
        .signal(
            "save",
            EntityKind::Item,
            DecaySpec::Exponential {
                half_life: Duration::from_secs(30 * 86_400),
            },
        )
        .windows(&[Window::AllTime])
        .velocity(false)
        .add();

    let _ = b
        .signal(
            "skip",
            EntityKind::Item,
            DecaySpec::Exponential {
                half_life: Duration::from_secs(86_400),
            },
        )
        .windows(&[Window::TwentyFourHours])
        .velocity(false)
        .add();

    let _ = b
        .signal(
            "share",
            EntityKind::Item,
            DecaySpec::Exponential {
                half_life: Duration::from_secs(14 * 86_400),
            },
        )
        .windows(&[Window::AllTime])
        .velocity(false)
        .add();

    // completion: emitted by the engine when dwell >= 15s. Recognized by
    // tidalDB as a positive engagement signal, which updates the user's
    // preference vector and closes the behavioral ranking loop.
    let _ = b
        .signal(
            "completion",
            EntityKind::Item,
            DecaySpec::Exponential {
                half_life: Duration::from_secs(60 * 86_400),
            },
        )
        .windows(&[Window::AllTime])
        .velocity(false)
        .add();

    b.text_field("title", TextFieldType::Text);
    b.text_field("category", TextFieldType::Keyword);

    // Embedding slot: dimensionality is set by the caller so it matches
    // whatever the embedder sidecar produces (8 for category-axis, 1536 for
    // OpenAI text-embedding-3-small).  The preference vector EMA and ANN
    // query always use this same space.
    b.embedding_slot("content", EntityKind::Item, embedding_dim);

    b.build().expect("forage schema is valid")
}
