<?php
declare(strict_types=1);

function send_message(PDO $db, int $senderId, int $receiverId, string $body): void {
  $body = trim($body);
  if ($body === '') throw new Exception("Mensaje vacío.");
  if ($senderId === $receiverId) throw new Exception("No puedes enviarte un mensaje a ti mismo.");
  $st = $db->prepare("INSERT INTO messages(sender_id,receiver_id,body,created_at) VALUES(?,?,?,?)");
  $st->execute([$senderId,$receiverId,$body,now_iso()]);
}

function list_inbox(PDO $db, int $userId, int $limit=50): array {
  $st = $db->prepare("
    SELECT m.*, u.username AS sender_username
    FROM messages m JOIN users u ON u.id=m.sender_id
    WHERE m.receiver_id=?
    ORDER BY m.created_at DESC
    LIMIT ?
  ");
  $st->execute([$userId,$limit]);
  return $st->fetchAll();
}

function list_sent(PDO $db, int $userId, int $limit=50): array {
  $st = $db->prepare("
    SELECT m.*, u.username AS receiver_username
    FROM messages m JOIN users u ON u.id=m.receiver_id
    WHERE m.sender_id=?
    ORDER BY m.created_at DESC
    LIMIT ?
  ");
  $st->execute([$userId,$limit]);
  return $st->fetchAll();
}

function mark_message_read(PDO $db, int $userId, int $msgId): void {
  $st = $db->prepare("UPDATE messages SET is_read=1 WHERE id=? AND receiver_id=?");
  $st->execute([$msgId,$userId]);
}

function admin_broadcast(PDO $db, int $adminId, string $title, string $body): void {
  $title = trim($title);
  $body = trim($body);
  if ($title === '' || $body === '') throw new Exception("Título y mensaje son obligatorios.");
  $st = $db->prepare("INSERT INTO broadcasts(sender_admin_id,title,body,created_at) VALUES(?,?,?,?)");
  $st->execute([$adminId,$title,$body,now_iso()]);
}

function get_unread_broadcast(PDO $db, int $userId): ?array {
  $st = $db->prepare("
    SELECT b.*
    FROM broadcasts b
    LEFT JOIN broadcast_reads r
      ON r.broadcast_id = b.id AND r.user_id = ?
    WHERE r.id IS NULL AND (b.is_active IS NULL OR b.is_active = 1)
    ORDER BY b.created_at DESC
    LIMIT 1
  ");
  $st->execute([$userId]);
  $row = $st->fetch();
  return $row ?: null;
}

function mark_broadcast_read(PDO $db, int $userId, int $broadcastId): void {
  // Safety: only mark as read if broadcast still exists; ignore FK issues on older/dirty DBs.
  $chk = $db->prepare("SELECT id FROM broadcasts WHERE id = ? LIMIT 1");
  $chk->execute([$broadcastId]);
  $row = $chk->fetch();
  if (!$row) return;

  try {
    $st = $db->prepare("INSERT OR IGNORE INTO broadcast_reads(broadcast_id,user_id,read_at) VALUES(?,?,?)");
    $st->execute([$broadcastId,$userId,now_iso()]);
  } catch (Throwable $e) {
    // Do not break the UI because of FK constraint errors on legacy DBs
    return;
  }
}
function list_broadcasts(PDO $db, int $limit=200): array {
  $st = $db->prepare("
    SELECT b.*, u.username AS sender_username
    FROM broadcasts b
    JOIN users u ON u.id=b.sender_admin_id
    ORDER BY b.created_at DESC
    LIMIT ?
  ");
  $st->execute([$limit]);
  return $st->fetchAll();
}

function set_broadcast_active(PDO $db, int $broadcastId, bool $active): void {
  $st = $db->prepare("UPDATE broadcasts SET is_active=?, canceled_at=? WHERE id=?");
  $st->execute([$active ? 1 : 0, $active ? null : now_iso(), $broadcastId]);
}

function delete_broadcast(PDO $db, int $broadcastId): void {
  $st = $db->prepare("DELETE FROM broadcasts WHERE id=?");
  $st->execute([$broadcastId]);
}


function delete_message(PDO $db, int $userId, int $msgId): void {
  $st = $db->prepare("SELECT sender_id, receiver_id FROM messages WHERE id=?");
  $st->execute([$msgId]);
  $m = $st->fetch();
  if (!$m) throw new Exception("Mensaje no encontrado.");
  if ((int)$m['sender_id'] !== $userId && (int)$m['receiver_id'] !== $userId) {
    throw new Exception("No tienes permiso para borrar este mensaje.");
  }
  $st = $db->prepare("DELETE FROM messages WHERE id=?");
  $st->execute([$msgId]);
}
