import { randomUUID } from "node:crypto";
import { getPool } from "../db/pool";
const DEFAULT_SETTINGS = {
    volume: 80,
    language: "id-ID",
    heartbeat_interval_seconds: 60
};
function nowIso() {
    return new Date().toISOString();
}
function mapConfig(row) {
    return {
        device_id: row.device_id,
        config_version: Number(row.config_version),
        settings_json: row.settings_json || {},
        updated_at: row.updated_at
    };
}
function mapAck(row) {
    return {
        id: row.id,
        device_id: row.device_id,
        config_version: Number(row.config_version),
        status: row.status,
        reason: row.reason || undefined,
        payload_json: row.payload_json || {},
        acked_at: row.acked_at
    };
}
export async function getDeviceConfig(deviceId) {
    const { rows } = await getPool().query("SELECT * FROM device_configs WHERE device_id = $1", [deviceId]);
    return rows[0] ? mapConfig(rows[0]) : null;
}
export async function getOrCreateDeviceConfig(deviceId) {
    const existing = await getDeviceConfig(deviceId);
    if (existing) {
        return existing;
    }
    return upsertDeviceConfig({
        device_id: deviceId,
        settings_json: DEFAULT_SETTINGS
    });
}
export async function upsertDeviceConfig(payload) {
    const existing = await getDeviceConfig(payload.device_id);
    const nextVersion = payload.config_version || (existing ? existing.config_version + 1 : 1);
    const { rows } = await getPool().query(`INSERT INTO device_configs (device_id, config_version, settings_json, updated_at)
     VALUES ($1,$2,$3,$4)
     ON CONFLICT (device_id) DO UPDATE
       SET config_version = EXCLUDED.config_version,
           settings_json = EXCLUDED.settings_json,
           updated_at = EXCLUDED.updated_at
     RETURNING *`, [payload.device_id, nextVersion, payload.settings_json, nowIso()]);
    return mapConfig(rows[0]);
}
export async function createDeviceConfigAck(payload) {
    const { rows } = await getPool().query(`INSERT INTO device_config_acks (
      id,
      device_id,
      config_version,
      status,
      reason,
      payload_json,
      acked_at
    ) VALUES ($1,$2,$3,$4,$5,$6,$7)
    RETURNING *`, [
        `cfgack_${randomUUID()}`,
        payload.device_id,
        payload.config_version,
        payload.status,
        payload.reason || null,
        payload.payload_json || {},
        nowIso()
    ]);
    return mapAck(rows[0]);
}
export async function listDeviceConfigAcks(deviceId, limit = 50) {
    const { rows } = await getPool().query(`SELECT * FROM device_config_acks
      WHERE device_id = $1
      ORDER BY acked_at DESC
      LIMIT $2`, [deviceId, Math.min(Math.max(limit, 1), 200)]);
    return rows.map(mapAck);
}
export async function getLatestDeviceConfigAck(deviceId) {
    const { rows } = await getPool().query(`SELECT * FROM device_config_acks
      WHERE device_id = $1
      ORDER BY acked_at DESC
      LIMIT 1`, [deviceId]);
    return rows[0] ? mapAck(rows[0]) : null;
}
export function toDeviceConfigPayload(config) {
    return { ...config };
}
export function toDeviceConfigAckPayload(ack) {
    return { ...ack };
}
