//! Estructura serializable del export firmado y constructor del bundle.

use crate::audit::reader::StoredEvent;
use serde::{Deserialize, Serialize};

pub const EXPORT_VERSION: &str = "kvendra-audit-export/v1";

/// Branding por defecto (Kvendra discreto). Se sobreescribe via
/// `audit.brand.*` en config.toml.
pub struct BrandDefaults {
    pub legal_name: &'static str,
    pub email: &'static str,
    pub color_hex: &'static str,
}

pub const BRAND_DEFAULT: BrandDefaults = BrandDefaults {
    legal_name: "Generated by Kvendra CLI",
    email: "",
    color_hex: "#A8FF38",
};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExportFilters {
    pub from: Option<String>,
    pub to: Option<String>,
    pub raw: Option<String>,
}

/// Una fila del export. Mantiene los campos necesarios para re-verificar
/// la cadena HMAC (mismo input que el `compute_hmac_v{1,2}`).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExportedEvent {
    pub audit_id: i64,
    pub timestamp_iso8601: String,
    pub ts_unix_ms: i64,
    pub profile_id: String,
    pub primitive: String,
    pub action: String,
    pub args_hash_hex: String,
    pub args_summary: String,
    pub result_status: String,
    pub severity: String,
    pub flags: String,
    pub previous_hmac_hex: String,
    pub current_hmac_hex: String,
    pub hmac_version: i64,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub remote_audit_id: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExportBundle {
    pub version: String,
    pub exported_at: String,
    pub exported_by: String,
    pub filters: ExportFilters,
    pub events: Vec<ExportedEvent>,
    pub chain_root_hmac_hex: String,
    pub chain_end_hmac_hex: String,
    pub chain_key_seed_hex: String,
    pub verifier_url: String,
}

/// Build the bundle from already-filtered + already-redacted stored events.
pub fn build_bundle(
    events: &[StoredEvent],
    exported_by: &str,
    filters: ExportFilters,
    chain_key_seed_hex: String,
) -> ExportBundle {
    let now = current_iso8601();
    let chain_root_hmac_hex = events.first().map(|e| e.prev_hmac_hex.clone()).unwrap_or_default();
    let chain_end_hmac_hex = events.last().map(|e| e.hmac_hex.clone()).unwrap_or_default();

    let exported_events: Vec<ExportedEvent> = events
        .iter()
        .map(|ev| ExportedEvent {
            audit_id: ev.id,
            timestamp_iso8601: ts_unix_ms_to_iso(ev.ts_unix_ms),
            ts_unix_ms: ev.ts_unix_ms,
            profile_id: ev.profile_id.clone(),
            primitive: ev.primitive.clone(),
            action: ev.action.clone(),
            args_hash_hex: ev.args_hash_hex.clone(),
            args_summary: super::redaction::redact_text(&format!(
                "{}:{}",
                ev.primitive, ev.action
            )),
            result_status: ev.status.clone(),
            severity: ev.severity.clone(),
            flags: ev.flags.clone(),
            previous_hmac_hex: ev.prev_hmac_hex.clone(),
            current_hmac_hex: ev.hmac_hex.clone(),
            hmac_version: ev.hmac_version,
            remote_audit_id: ev.remote_audit_id.clone(),
        })
        .collect();

    ExportBundle {
        version: EXPORT_VERSION.to_string(),
        exported_at: now,
        exported_by: exported_by.to_string(),
        filters,
        events: exported_events,
        chain_root_hmac_hex,
        chain_end_hmac_hex,
        chain_key_seed_hex,
        verifier_url: "https://app.kvendra.cloud/audit-verify".to_string(),
    }
}

fn current_iso8601() -> String {
    use time::OffsetDateTime;
    use time::format_description::well_known::Rfc3339;
    OffsetDateTime::now_utc().format(&Rfc3339).unwrap_or_default()
}

fn ts_unix_ms_to_iso(ms: i64) -> String {
    use time::OffsetDateTime;
    use time::format_description::well_known::Rfc3339;
    let secs = ms / 1000;
    match OffsetDateTime::from_unix_timestamp(secs) {
        Ok(t) => t.format(&Rfc3339).unwrap_or_else(|_| format!("{ms}ms")),
        Err(_) => format!("{ms}ms"),
    }
}
