use axum::Json;
use axum::extract::Extension;
use serde::Deserialize;
use tracing;

use erp_core::error::AppError;
use erp_core::rbac::require_permission;
use erp_core::types::{ApiResponse, TenantContext};

const MAX_EVENTS_PER_BATCH: usize = 100;

#[derive(Debug, Deserialize)]
#[allow(dead_code)] // 客户端上报结构体，字段后续接入分析表时使用
pub struct AnalyticsEvent {
    pub event: String,
    pub properties: Option<serde_json::Value>,
    #[serde(deserialize_with = "deserialize_flexible_timestamp")]
    pub timestamp: Option<String>,
    pub page: Option<String>,
    pub user_id: Option<String>,
    pub patient_id: Option<String>,
}

fn deserialize_flexible_timestamp<'de, D>(de: D) -> Result<Option<String>, D::Error>
where
    D: serde::Deserializer<'de>,
{
    use serde::de;
    let val = Option::<serde_json::Value>::deserialize(de)?;
    match val {
        None => Ok(None),
        Some(serde_json::Value::String(s)) => Ok(Some(s)),
        Some(serde_json::Value::Number(n)) => Ok(Some(n.to_string())),
        _ => Err(de::Error::custom("timestamp must be string or number")),
    }
}

#[derive(Debug, Deserialize)]
pub struct BatchRequest {
    pub events: Vec<AnalyticsEvent>,
}

/// 接收小程序批量埋点事件。
/// 当前为日志记录模式 — 后续可接入 ClickHouse/PostgreSQL 分析表。
pub async fn batch(
    Extension(ctx): Extension<TenantContext>,
    Json(req): Json<BatchRequest>,
) -> Result<Json<ApiResponse<()>>, AppError> {
    require_permission(&ctx, "system.analytics.submit")?;
    if req.events.len() > MAX_EVENTS_PER_BATCH {
        return Err(AppError::Validation(format!(
            "批量埋点事件数不能超过 {} 条",
            MAX_EVENTS_PER_BATCH
        )));
    }
    for evt in &req.events {
        tracing::info!(
            event = %evt.event,
            page = ?evt.page,
            properties = ?evt.properties,
            "Analytics event received"
        );
    }
    Ok(Json(ApiResponse::ok(())))
}
