<?php
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit;
}

$DB_HOST = 'localhost';
$DB_NAME = 'pnartli1_doorkar';
$DB_USER = 'pnartli1_doorkar';
$DB_PASS = 'V[B5S(1gO,OIqPvz';

const ONLINE_THRESHOLD_SECONDS = 75;

function respond($success, $data = [], $message = '') {
    echo json_encode(
        array_merge([
            'success' => $success,
            'message' => $message
        ], $data),
        JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
    );
    exit;
}

function input_json() {
    $raw = file_get_contents('php://input');
    $json = json_decode($raw, true);
    return is_array($json) ? $json : [];
}

function fetch_one(PDO $pdo, $sql, $params = []) {
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return is_array($row) ? $row : null;
    } catch (Throwable $e) {
        return null;
    }
}

function verify_session(PDO $pdo, $userId, $apiToken) {
    if ($userId <= 0 || trim($apiToken) === '') {
        return false;
    }

    $user = fetch_one(
        $pdo,
        "SELECT id, api_token_hash FROM users WHERE id = ? LIMIT 1",
        [$userId]
    );

    if (!$user) return false;

    $storedHash = trim((string)($user['api_token_hash'] ?? ''));
    if ($storedHash === '') return false;

    if (preg_match('/^[a-f0-9]{64}$/i', $storedHash)) {
        return hash_equals(
            strtolower($storedHash),
            hash('sha256', $apiToken)
        );
    }

    if (str_starts_with($storedHash, '$2y$') || str_starts_with($storedHash, '$argon2')) {
        return password_verify($apiToken, $storedHash);
    }

    return false;
}

function ensure_presence_table(PDO $pdo) {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS user_presence (
            user_id INT(11) NOT NULL,
            last_seen_at DATETIME NOT NULL,
            app_state ENUM('online','offline') NOT NULL DEFAULT 'online',
            platform VARCHAR(30) NOT NULL DEFAULT 'android',
            updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (user_id),
            INDEX idx_last_seen_at (last_seen_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ");
}

function upsert_online(PDO $pdo, $userId) {
    $stmt = $pdo->prepare("
        INSERT INTO user_presence (user_id, last_seen_at, app_state, platform)
        VALUES (?, NOW(), 'online', 'android')
        ON DUPLICATE KEY UPDATE
            last_seen_at = NOW(),
            app_state = 'online',
            platform = 'android',
            updated_at = CURRENT_TIMESTAMP
    ");
    $stmt->execute([$userId]);
}

function mark_offline(PDO $pdo, $userId) {
    $stmt = $pdo->prepare("
        INSERT INTO user_presence (user_id, last_seen_at, app_state, platform)
        VALUES (?, DATE_SUB(NOW(), INTERVAL 999 SECOND), 'offline', 'android')
        ON DUPLICATE KEY UPDATE
            last_seen_at = DATE_SUB(NOW(), INTERVAL 999 SECOND),
            app_state = 'offline',
            platform = 'android',
            updated_at = CURRENT_TIMESTAMP
    ");
    $stmt->execute([$userId]);
}

function presence_summary(PDO $pdo, $userId) {
    $row = fetch_one(
        $pdo,
        "SELECT user_id, last_seen_at, app_state FROM user_presence WHERE user_id = ? LIMIT 1",
        [$userId]
    );

    if (!$row) {
        return [
            'user_id' => (int)$userId,
            'is_online' => false,
            'status_text' => 'آفلاین',
            'last_seen_text' => 'نامشخص',
            'last_seen_at' => null
        ];
    }

    $lastSeen = (string)($row['last_seen_at'] ?? '');
    $seconds = 999999;

    if ($lastSeen !== '') {
        $seconds = max(0, time() - strtotime($lastSeen));
    }

    $isOnline = $seconds <= ONLINE_THRESHOLD_SECONDS && ($row['app_state'] ?? '') !== 'offline';

    if ($isOnline) {
        $lastSeenText = 'همین الان آنلاین است';
    } elseif ($seconds < 3600) {
        $minutes = max(1, (int)floor($seconds / 60));
        $lastSeenText = $minutes . ' دقیقه پیش';
    } elseif ($seconds < 86400) {
        $hours = max(1, (int)floor($seconds / 3600));
        $lastSeenText = $hours . ' ساعت پیش';
    } else {
        $days = max(1, (int)floor($seconds / 86400));
        $lastSeenText = $days . ' روز پیش';
    }

    return [
        'user_id' => (int)$userId,
        'is_online' => $isOnline,
        'status_text' => $isOnline ? 'آنلاین' : 'آفلاین',
        'last_seen_text' => $lastSeenText,
        'last_seen_at' => $lastSeen
    ];
}

try {
    $pdo = new PDO(
        "mysql:host={$DB_HOST};dbname={$DB_NAME};charset=utf8mb4",
        $DB_USER,
        $DB_PASS,
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ]
    );
    ensure_presence_table($pdo);
} catch (Throwable $e) {
    respond(false, [], 'اتصال به دیتابیس برقرار نشد');
}

$input = input_json();
$action = trim((string)($input['action'] ?? ''));
$userId = (int)($input['user_id'] ?? 0);
$apiToken = trim((string)($input['api_token'] ?? ''));

if (!verify_session($pdo, $userId, $apiToken)) {
    respond(false, [], 'نشست ورود معتبر نیست؛ دوباره وارد حساب شو');
}

if ($action === 'update_presence') {
    upsert_online($pdo, $userId);
    respond(true, [
        'presence' => presence_summary($pdo, $userId)
    ], 'وضعیت آنلاین ثبت شد');
}

if ($action === 'mark_offline') {
    mark_offline($pdo, $userId);
    respond(true, [
        'presence' => presence_summary($pdo, $userId)
    ], 'وضعیت آفلاین ثبت شد');
}

if ($action === 'get_presence') {
    $targetUserId = (int)($input['target_user_id'] ?? $userId);
    if ($targetUserId <= 0) {
        $targetUserId = $userId;
    }

    respond(true, [
        'presence' => presence_summary($pdo, $targetUserId)
    ], 'وضعیت کاربر دریافت شد');
}

respond(false, [], 'درخواست نامعتبر است');
