//! Timing metrics for crawler operations (see `crawl_metrics` table, 0028).
//!
//! One [`OpRow`] per completed operation (manga list walk, manga detail,
//! cover, whole chapter); [`OpSummary`] is the per-type average roll-up that
//! drives the admin Metrics tab. Per-page crawl timing is derived on the
//! client from the `chapter` summary's `avg_items` (pages/chapter), not
//! stored per image. Analysis duration lives on `page_analysis`, not here.

use chrono::{DateTime, Utc};
use serde::Serialize;
use sqlx::FromRow;
use uuid::Uuid;

/// One time bucket of a metrics series — count, ok/failed split, and mean
/// duration over the bucket. Shared by the crawl-ops and analysis trend
/// charts (both are `{t, n, ok, failed, avg_ms}` over a `date_trunc` window).
/// Empty intervals are simply absent; the client fills the continuous axis.
#[derive(Debug, Clone, Serialize, FromRow)]
pub struct MetricsBucket {
    /// Bucket start (`date_trunc(unit, finished_at|analyzed_at)`).
    pub t: DateTime<Utc>,
    pub n: i64,
    pub ok: i64,
    pub failed: i64,
    pub avg_ms: Option<f64>,
}

/// Per-operation-type average roll-up over a time window.
#[derive(Debug, Clone, Serialize, FromRow)]
pub struct OpSummary {
    /// `manga_list` | `manga_detail` | `manga_cover` | `chapter`.
    pub op: String,
    /// Mean duration in milliseconds (`NULL`→absent only when `n = 0`).
    pub avg_ms: Option<f64>,
    /// Total operations in the window.
    pub n: i64,
    pub ok: i64,
    pub failed: i64,
    /// Mean `items` (pages/chapter, mangas/list-walk); `None` when unused.
    pub avg_items: Option<f64>,
}

/// One timed operation, resolved to manga/chapter labels for the recent-ops log.
#[derive(Debug, Clone, Serialize, FromRow)]
pub struct OpRow {
    pub id: Uuid,
    pub op: String,
    pub manga_id: Option<Uuid>,
    pub manga_title: Option<String>,
    pub chapter_id: Option<Uuid>,
    pub chapter_number: Option<i32>,
    pub outcome: String,
    pub duration_ms: i64,
    pub items: Option<i32>,
    pub error: Option<String>,
    pub finished_at: DateTime<Utc>,
}
