<?php
// ============================================================
//  MediCore — Push Message Center API
//  File: api/push-messages.php
//  Administrator broadcasts, targeted all / branch-wise / user-wise.
// ============================================================
require_once '../includes/db.php';
require_once '../includes/auth.php';
require_once '../includes/notify.php';
require_login();
session_write_close();

ensure_topbar_tables();

header('Content-Type: application/json');

$body   = json_decode(file_get_contents('php://input'), true) ?? [];
$action = trim($body['action'] ?? '');

try {
    match ($action) {
        'list'         => api_list($body),
        'send'         => api_send($body),
        'mark_read'    => api_mark_read($body),
        'unread_count' => api_unread_count($body),
        'branches'     => api_branches($body),
        'users'        => api_users($body),
        default        => fail('Unknown action')
    };
} catch (Throwable $e) {
    fail($e->getMessage());
}

// ── List messages targeted at the current user ──────────────────
function api_list(array $b): void {
    $uid = current_user_id();

    $page     = max(1, (int)($b['page'] ?? 1));
    $pageSize = max(5, min(100, (int)($b['page_size'] ?? 20)));
    $offset   = ($page - 1) * $pageSize;

    $total = (int) db_val(
        "SELECT COUNT(*) FROM push_message_recipients WHERE user_id = ?", [$uid]
    );
    $rows = db_rows(
        "SELECT pm.id, pm.title, pm.message, pm.created_at,
                u.name AS sender_name,
                pmr.is_read, pmr.read_at
           FROM push_message_recipients pmr
           JOIN push_messages pm ON pm.id = pmr.push_message_id
      LEFT JOIN users u ON u.id = pm.sender_id
          WHERE pmr.user_id = ?
       ORDER BY pm.created_at DESC
          LIMIT $pageSize OFFSET $offset",
        [$uid]
    );

    ok([
        'data'        => $rows,
        'page'        => $page,
        'total'       => $total,
        'total_pages' => (int) max(1, ceil($total / $pageSize)),
        'unread'      => (int) db_val(
            "SELECT COUNT(*) FROM push_message_recipients WHERE user_id = ? AND is_read = 0", [$uid]
        ),
    ]);
}

// ── Send a broadcast (admin only) ────────────────────────────────
function api_send(array $b): void {
    require_admin();

    $title      = trim($b['title']   ?? '');
    $message    = trim($b['message'] ?? '');
    $targetType = trim($b['target_type'] ?? 'all');
    $branchId   = (int)($b['target_branch_id'] ?? 0);
    $targetUid  = (int)($b['target_user_id']   ?? 0);

    if (!$title)   fail('Title is required.');
    if (!$message) fail('Message is required.');
    if (!in_array($targetType, ['all','branch','user'])) fail('Invalid target type.');
    if ($targetType === 'branch' && !$branchId)  fail('Select a branch to target.');
    if ($targetType === 'user'   && !$targetUid) fail('Select a user to target.');

    $recipients = match ($targetType) {
        'branch' => array_map(fn($r) => (int)$r['id'],
            db_rows("SELECT id FROM users WHERE is_active = 1 AND branch_id = ?", [$branchId])),
        'user'   => [$targetUid],
        default  => array_map(fn($r) => (int)$r['id'],
            db_rows("SELECT id FROM users WHERE is_active = 1")),
    };
    if (!$recipients) fail('No matching recipients for that target.');

    db()->beginTransaction();
    try {
        $msgId = db_insert(
            "INSERT INTO push_messages
               (title, message, sender_id, target_type, target_branch_id, target_user_id)
             VALUES (?,?,?,?,?,?)",
            [$title, $message, current_user_id(), $targetType,
             $targetType === 'branch' ? $branchId : null,
             $targetType === 'user'   ? $targetUid : null]
        );

        foreach ($recipients as $rid) {
            db_run(
                "INSERT IGNORE INTO push_message_recipients (push_message_id, user_id)
                 VALUES (?,?)",
                [$msgId, $rid]
            );
        }

        db()->commit();
        ok(['id' => $msgId, 'recipient_count' => count($recipients)]);
    } catch (Throwable $e) {
        db()->rollBack();
        fail('Send failed: ' . $e->getMessage());
    }
}

// ── Mark one as read ──────────────────────────────────────────
function api_mark_read(array $b): void {
    $uid = current_user_id();
    $id  = (int)($b['id'] ?? 0);
    if (!$id) fail('Missing id');

    db_run(
        "UPDATE push_message_recipients SET is_read = 1, read_at = NOW()
          WHERE push_message_id = ? AND user_id = ?",
        [$id, $uid]
    );
    ok();
}

function api_unread_count(array $b): void {
    $uid = current_user_id();
    ok(['unread' => (int) db_val(
        "SELECT COUNT(*) FROM push_message_recipients WHERE user_id = ? AND is_read = 0", [$uid]
    )]);
}

// ── Helper lookups for the compose form ──────────────────────────
function api_branches(array $b): void {
    ok(['data' => db_rows("SELECT id, name FROM branches WHERE is_active = 1 ORDER BY name")]);
}
function api_users(array $b): void {
    ok(['data' => db_rows("SELECT id, name, role FROM users WHERE is_active = 1 ORDER BY name")]);
}

function ok(array $extra = []): void {
    echo json_encode(array_merge(['success' => true], $extra));
    exit;
}
function fail(string $msg): never {
    echo json_encode(['success' => false, 'error' => $msg]);
    exit;
}
