// Remote machine persistence — stores machine configs + SPKI pins in SQLite

use crate::error::AppError;
use crate::session::SessionDb;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoteMachineRecord {
    pub id: String,
    pub label: String,
    pub url: String,
    pub token: String,
    pub auto_connect: bool,
    pub spki_pins: Vec<String>,
}

impl SessionDb {
    pub fn save_remote_machine(&self, machine: &RemoteMachineRecord) -> Result<(), AppError> {
        let conn = self.conn.lock().unwrap();
        let pins_json = serde_json::to_string(&machine.spki_pins)?;
        let now = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap_or_default()
            .as_secs() as i64;
        conn.execute(
            "INSERT OR REPLACE INTO remote_machines (id, label, url, token, auto_connect, spki_pins, created_at, updated_at)
             VALUES (?1, ?2, ?3, ?4, ?5, ?6, COALESCE((SELECT created_at FROM remote_machines WHERE id = ?1), ?7), ?7)",
            rusqlite::params![machine.id, machine.label, machine.url, machine.token, machine.auto_connect as i32, pins_json, now],
        )?;
        Ok(())
    }

    pub fn load_remote_machines(&self) -> Result<Vec<RemoteMachineRecord>, AppError> {
        let conn = self.conn.lock().unwrap();
        let mut stmt = conn.prepare(
            "SELECT id, label, url, token, auto_connect, spki_pins FROM remote_machines"
        )?;
        let rows = stmt.query_map([], |row| {
            let pins_json: String = row.get("spki_pins")?;
            let pins: Vec<String> = serde_json::from_str(&pins_json).unwrap_or_default();
            Ok(RemoteMachineRecord {
                id: row.get("id")?,
                label: row.get("label")?,
                url: row.get("url")?,
                token: row.get("token")?,
                auto_connect: row.get::<_, i32>("auto_connect")? != 0,
                spki_pins: pins,
            })
        })?;
        let mut machines = Vec::new();
        for row in rows {
            machines.push(row?);
        }
        Ok(machines)
    }

    pub fn delete_remote_machine(&self, id: &str) -> Result<(), AppError> {
        let conn = self.conn.lock().unwrap();
        conn.execute("DELETE FROM remote_machines WHERE id = ?1", [id])?;
        Ok(())
    }

    pub fn update_remote_machine_pins(&self, id: &str, pins: &[String]) -> Result<(), AppError> {
        let conn = self.conn.lock().unwrap();
        let pins_json = serde_json::to_string(pins)?;
        let now = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap_or_default()
            .as_secs() as i64;
        conn.execute(
            "UPDATE remote_machines SET spki_pins = ?1, updated_at = ?2 WHERE id = ?3",
            rusqlite::params![pins_json, now, id],
        )?;
        Ok(())
    }
}
