//! Recordings — list-only. Adding a streaming download handler is a
//! follow-up; for now the operator looks at the filenames + sizes and
//! pulls files from `--recording-dir` directly.

use super::shared::{fmt_unix, html_escape, require_admin};
use crate::api::error::ApiError;
use crate::api::middleware::AuthedUser;
use crate::api::state::AppState;
use axum::extract::Extension;
use axum::response::Html;
use std::fmt::Write as _;
use std::sync::Arc;

const PAGE_SIZE: i64 = 200;

pub async fn index(
    Extension(state): Extension<Arc<AppState>>,
    admin: AuthedUser,
) -> Result<Html<String>, ApiError> {
    require_admin(&admin)?;
    let rows = state
        .db
        .recordings_list(PAGE_SIZE)
        .await
        .map_err(|e| ApiError::Internal(e.to_string()))?;
    let mut s = String::new();
    s.push_str(
        r##"<div class="space-y-4">
  <header>
    <h2 class="text-lg font-semibold">Recordings</h2>
    <p class="text-xs text-slate-500 mt-1">Files live under <code>--recording-dir</code>. Pull them with <code>scp</code> / <code>rsync</code> for now; an in-browser download is coming.</p>
  </header>"##,
    );
    if rows.is_empty() {
        s.push_str(
            r##"<p class="text-slate-500 text-sm">No session recordings yet.</p></div>"##,
        );
        return Ok(Html(s));
    }
    s.push_str(
        r##"<div class="rounded-md border border-slate-800 bg-slate-900 overflow-hidden">
  <table class="w-full text-sm">
    <thead class="text-xs uppercase text-slate-500 bg-slate-950"><tr>
      <th class="text-left font-medium px-3 py-2">Filename</th>
      <th class="text-left font-medium px-3 py-2">Peer</th>
      <th class="text-left font-medium px-3 py-2">Size</th>
      <th class="text-left font-medium px-3 py-2">State</th>
      <th class="text-left font-medium px-3 py-2">Started</th>
      <th class="text-left font-medium px-3 py-2">Finished</th>
    </tr></thead>
    <tbody class="divide-y divide-slate-800">"##,
    );
    for r in &rows {
        let _ = write!(
            s,
            r##"<tr>
  <td class="px-3 py-2 font-mono text-slate-200 text-xs">{file}</td>
  <td class="px-3 py-2 font-mono text-slate-300">{peer}</td>
  <td class="px-3 py-2 text-slate-400">{size}</td>
  <td class="px-3 py-2 text-slate-400">{state}</td>
  <td class="px-3 py-2 text-slate-500 text-xs">{started}</td>
  <td class="px-3 py-2 text-slate-500 text-xs">{finished}</td>
</tr>"##,
            file = html_escape(&r.filename),
            peer = html_escape(&r.peer_id),
            size = human_size(r.size),
            state = html_escape(&r.state),
            started = html_escape(&fmt_unix(r.started_at)),
            finished = html_escape(&r.finished_at.map(fmt_unix).unwrap_or_else(|| "—".into()))
        );
    }
    s.push_str("</tbody></table></div></div>");
    Ok(Html(s))
}

fn human_size(bytes: i64) -> String {
    let b = bytes as f64;
    if bytes < 1024 {
        format!("{} B", bytes)
    } else if b < 1024.0 * 1024.0 {
        format!("{:.1} KiB", b / 1024.0)
    } else if b < 1024.0 * 1024.0 * 1024.0 {
        format!("{:.1} MiB", b / (1024.0 * 1024.0))
    } else {
        format!("{:.2} GiB", b / (1024.0 * 1024.0 * 1024.0))
    }
}
