//! 设备日志 API — 分页列表查询

use axum::extract::{Query, State};
use axum::Json;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};

use crate::error::AppError;
use crate::middleware::auth::{self, CurrentUser};

/// 设备日志查询参数
#[derive(Debug, Deserialize)]
pub struct DeviceLogQuery {
    pub cabinet_id: Option<i64>,
    pub log_type: Option<i8>,
    pub start_time: Option<String>,
    pub end_time: Option<String>,
    #[serde(default = "default_page")]
    pub page: i64,
    #[serde(default = "default_page_size")]
    pub page_size: i64,
}

/// 设备日志列表项
#[derive(Debug, Serialize)]
pub struct DeviceLogItem {
    pub id: i64,
    pub cabinet_id: i64,
    pub cabinet_name: Option<String>,
    pub log_type: i8,
    pub log_type_text: String,
    pub content: Option<String>,
    pub created_at: Option<String>,
}

fn default_page() -> i64 { 1 }
fn default_page_size() -> i64 { 20 }

/// 日志类型码转中文
fn log_type_text(log_type: i8) -> &'static str {
    match log_type {
        1 => "状态上报",
        2 => "故障",
        3 => "告警",
        4 => "停电",
        _ => "未知",
    }
}

/// 数据库行映射
#[derive(Debug, sqlx::FromRow)]
struct DeviceLogRow {
    id: i64,
    cabinet_id: i64,
    cabinet_name: Option<String>,
    log_type: i8,
    content: Option<String>,
    created_at: Option<NaiveDateTime>,
}

/// GET /api/device-logs — 设备日志分页列表
pub async fn list_device_logs(
    user: CurrentUser,
    State(state): State<super::AppState>,
    Query(params): Query<DeviceLogQuery>,
) -> Result<Json<Value>, AppError> {
    auth::check_permission(&user, "device_log:view")?;
    let offset = (params.page - 1) * params.page_size;

    // 构建 WHERE 条件
    let mut conditions = Vec::new();
    let mut bind_values: Vec<String> = Vec::new();

    if let Some(cabinet_id) = params.cabinet_id {
        conditions.push("dl.cabinet_id = ?");
        bind_values.push(cabinet_id.to_string());
    }
    if let Some(log_type) = params.log_type {
        conditions.push("dl.log_type = ?");
        bind_values.push(log_type.to_string());
    }
    if let Some(ref start_time) = params.start_time {
        conditions.push("dl.created_at >= ?");
        bind_values.push(start_time.clone());
    }
    if let Some(ref end_time) = params.end_time {
        conditions.push("dl.created_at <= ?");
        bind_values.push(end_time.clone());
    }

    // 追加组织数据隔离
    let (org_cond, org_binds) = auth::org_condition(&user, "dl");
    if !org_cond.is_empty() {
        conditions.push(org_cond.trim_start_matches(" AND "));
        bind_values.extend(org_binds);
    }

    let where_clause = if conditions.is_empty() {
        String::new()
    } else {
        format!("WHERE {}", conditions.join(" AND "))
    };

    // 查询总数
    let count_sql = format!(
        "SELECT COUNT(*) FROM device_logs dl {}",
        where_clause
    );
    let mut count_query = sqlx::query_scalar::<_, i64>(&count_sql);
    for val in &bind_values {
        count_query = count_query.bind(val);
    }
    let total = count_query.fetch_one(&state.mysql).await?;

    // 查询列表
    let list_sql = format!(
        "SELECT dl.id, dl.cabinet_id, c.name AS cabinet_name, \
         dl.log_type, dl.content, dl.created_at \
         FROM device_logs dl \
         LEFT JOIN cabinets c ON dl.cabinet_id = c.id \
         {} ORDER BY dl.created_at DESC LIMIT ? OFFSET ?",
        where_clause
    );

    let mut list_query = sqlx::query_as::<_, DeviceLogRow>(&list_sql);
    for val in &bind_values {
        list_query = list_query.bind(val);
    }
    list_query = list_query.bind(params.page_size).bind(offset);

    let rows = list_query.fetch_all(&state.mysql).await?;

    let list: Vec<DeviceLogItem> = rows
        .into_iter()
        .map(|r| DeviceLogItem {
            id: r.id,
            cabinet_id: r.cabinet_id,
            cabinet_name: r.cabinet_name,
            log_type: r.log_type,
            log_type_text: log_type_text(r.log_type).to_string(),
            content: r.content,
            created_at: r.created_at.map(|t| t.to_string()),
        })
        .collect();

    Ok(Json(json!({
        "code": 0,
        "data": {
            "list": list,
            "total": total,
            "page": params.page,
            "page_size": params.page_size,
        },
        "message": "ok"
    })))
}
