import { randomUUID } from "node:crypto";
import { getPool } from "../db/pool";
function nowIso() {
    return new Date().toISOString();
}
function normalizeStatus(status) {
    if (status === "accepted" || status === "delivered" || status === "failed" || status === "timeout") {
        return status;
    }
    return "accepted";
}
function mapCommand(row) {
    return {
        id: row.id,
        device_id: row.device_id,
        command: row.command,
        payload: row.payload_json || {},
        status: row.status,
        requested_at: row.requested_at,
        acknowledged_at: row.acknowledged_at || null,
        result_payload: row.result_payload_json || null,
        reason: row.reason || null
    };
}
export async function createDeviceCommand(payload) {
    const entity = {
        id: `cmd_${randomUUID()}`,
        device_id: payload.device_id,
        command: payload.command,
        payload: payload.payload || {},
        status: normalizeStatus(payload.status || "accepted"),
        requested_at: nowIso(),
        acknowledged_at: null,
        result_payload: null,
        reason: null
    };
    const { rows } = await getPool().query(`INSERT INTO device_commands (
      id,
      device_id,
      command,
      payload_json,
      status,
      requested_at,
      acknowledged_at,
      result_payload_json,
      reason
    ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)
    RETURNING *`, [
        entity.id,
        entity.device_id,
        entity.command,
        entity.payload,
        entity.status,
        entity.requested_at,
        entity.acknowledged_at,
        entity.result_payload,
        entity.reason
    ]);
    return mapCommand(rows[0]);
}
export async function listDeviceCommands(deviceId) {
    const { rows } = await getPool().query("SELECT * FROM device_commands WHERE device_id = $1 ORDER BY requested_at DESC", [deviceId]);
    return rows.map(mapCommand);
}
export async function getDeviceCommandById(deviceId, commandId) {
    const { rows } = await getPool().query("SELECT * FROM device_commands WHERE device_id = $1 AND id = $2", [deviceId, commandId]);
    return rows[0] ? mapCommand(rows[0]) : null;
}
export function toDeviceCommandPayload(command) {
    return mapCommand(command);
}
export function toDeviceCommandPayloadBrief(command) {
    return {
        command_id: command.id,
        device_id: command.device_id,
        command: command.command,
        status: command.status,
        requested_at: command.requested_at,
        acknowledged_at: command.acknowledged_at
    };
}
export async function acknowledgeDeviceCommand(payload) {
    const now = nowIso();
    const { rows } = await getPool().query(`UPDATE device_commands
        SET status = $3,
            acknowledged_at = $4,
            result_payload_json = $5,
            reason = $6
      WHERE device_id = $1 AND id = $2
      RETURNING *`, [payload.device_id, payload.command_id, payload.status, now, payload.result_payload || null, payload.reason || null]);
    return rows[0] ? mapCommand(rows[0]) : null;
}
