<?php
/**
 * Sync attendance log from a ZKTeco device into zk_attendance_log.
 * Optionally maps zk_user_id to user_id via user_zk_mapping.
 * Returns JSON: success, message, count, last_error.
 */
session_start();
header('Content-Type: application/json');

require_once __DIR__ . '/../layouts/dbconn.php';
require_once __DIR__ . '/../layouts/session.php';
require_once __DIR__ . '/../includes/ZKTecoConnector.php';

if (!isset($_SESSION['user_id'])) {
    echo json_encode(['success' => false, 'message' => 'Unauthorized']);
    exit;
}

$allowed_roles = ['SUPER_ADMIN', 'HOSPITAL_ADMIN'];
if (!in_array($_SESSION['role_code'] ?? '', $allowed_roles)) {
    echo json_encode(['success' => false, 'message' => 'Access denied']);
    exit;
}

$device_id = isset($_POST['device_id']) ? (int) $_POST['device_id'] : (isset($_GET['device_id']) ? (int) $_GET['device_id'] : 0);
if ($device_id <= 0) {
    echo json_encode(['success' => false, 'message' => 'Invalid device_id']);
    exit;
}

$stmt = $conn->prepare("SELECT device_id, name, ip_address, port FROM zk_devices WHERE device_id = ? AND is_active = 1");
$stmt->bind_param("i", $device_id);
$stmt->execute();
$res = $stmt->get_result();
$device = $res ? $res->fetch_assoc() : null;
$stmt->close();

if (!$device) {
    echo json_encode(['success' => false, 'message' => 'Device not found or inactive']);
    exit;
}

$zk = new ZKTecoConnector();
$zk->setTimeout(8);
if (!$zk->connect($device['ip_address'], (int) $device['port'])) {
    $err = $zk->getLastError();
    $conn->query("UPDATE zk_devices SET last_sync_at = NOW(), last_sync_status = 'ERROR', last_sync_message = '" . $conn->real_escape_string($err) . "' WHERE device_id = " . (int) $device_id);
    echo json_encode(['success' => false, 'message' => 'Device connection failed', 'last_error' => $err]);
    exit;
}

$records = $zk->getAttendanceLog();
$zk->disconnect();

// Load mapping device_id -> zk_user_id -> user_id
$map = [];
$mapRes = $conn->query("SELECT zk_user_id, user_id FROM user_zk_mapping WHERE device_id = " . (int) $device_id);
if ($mapRes) {
    while ($row = $mapRes->fetch_assoc()) {
        $map[$row['zk_user_id']] = (int) $row['user_id'];
    }
}

$inserted = 0;
$now = date('Y-m-d H:i:s');
$ins = $conn->prepare("INSERT INTO zk_attendance_log (device_id, zk_user_id, zk_badge_no, punch_time, punch_state, user_id, synced_at) VALUES (?, ?, ?, ?, ?, ?, ?)");
$check = $conn->prepare("SELECT 1 FROM zk_attendance_log WHERE device_id = ? AND zk_user_id = ? AND punch_time = ? LIMIT 1");

foreach ($records as $r) {
    $check->bind_param("iss", $device_id, $r['zk_user_id'], $r['punch_time']);
    $check->execute();
    if ($check->get_result()->num_rows > 0) {
        continue;
    }
    $uid = isset($map[$r['zk_user_id']]) ? $map[$r['zk_user_id']] : null;
    $ins->bind_param("issssis", $device_id, $r['zk_user_id'], $r['zk_badge_no'], $r['punch_time'], $r['punch_state'], $uid, $now);
    $ins->execute();
    $inserted++;
}

$conn->query("UPDATE zk_devices SET last_sync_at = NOW(), last_sync_status = 'OK', last_sync_message = " . (int) $inserted . " WHERE device_id = " . (int) $device_id);

echo json_encode([
    'success' => true,
    'message' => 'Synced successfully',
    'count' => $inserted,
    'total_from_device' => count($records),
]);
