<?php
require_once __DIR__ . '/../config.php';
header('Content-Type: application/json');
header('X-Content-Type-Options: nosniff');

$action = $_POST['action'] ?? $_GET['action'] ?? '';

function jsonOut(bool $ok, string $msg, array $data = []): void {
    echo json_encode(array_merge(['ok' => $ok, 'msg' => $msg], $data));
    exit;
}

function logActivity(?int $uid, string $action, string $detail = ''): void {
    try {
        $db = getDB();
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
        $st = $db->prepare("INSERT INTO fg_activity_log (user_id,action,detail,ip_address) VALUES (?,?,?,?)");
        $st->execute([$uid, $action, $detail, substr($ip, 0, 45)]);
    } catch (\Throwable $e) { /* silent */ }
}

function parseDeviceName(string $ua): string {
    $name = 'Unknown Device';
    if (preg_match('/iPhone/', $ua)) $name = 'iPhone';
    elseif (preg_match('/iPad/', $ua)) $name = 'iPad';
    elseif (preg_match('/Android.*Mobile/', $ua)) $name = 'Android Phone';
    elseif (preg_match('/Android/', $ua)) $name = 'Android Tablet';
    elseif (preg_match('/Windows NT/', $ua)) {
        if (preg_match('/Chrome\/(\d+)/', $ua, $m)) $name = "Windows/Chrome {$m[1]}";
        elseif (preg_match('/Firefox\/(\d+)/', $ua, $m)) $name = "Windows/Firefox {$m[1]}";
        elseif (preg_match('/Edg\/(\d+)/', $ua, $m)) $name = "Windows/Edge {$m[1]}";
        else $name = 'Windows Browser';
    } elseif (preg_match('/Macintosh/', $ua)) {
        if (preg_match('/Chrome\/(\d+)/', $ua, $m)) $name = "Mac/Chrome {$m[1]}";
        elseif (preg_match('/Safari\//', $ua)) $name = 'Mac/Safari';
        else $name = 'Mac Browser';
    } elseif (preg_match('/Linux/', $ua)) $name = 'Linux Browser';
    return substr($name, 0, 100);
}

// ── LOGIN ─────────────────────────────────────────────────────
if ($action === 'login') {
    $username = trim($_POST['username'] ?? '');
    $password = $_POST['password'] ?? '';
    if (!$username || !$password) jsonOut(false, 'Username dan password harus diisi.');

    $db = getDB();
    $st = $db->prepare("SELECT * FROM fg_users WHERE username = ? OR email = ? LIMIT 1");
    $st->execute([$username, $username]);
    $user = $st->fetch();

    if (!$user || !password_verify($password, $user['password_hash'])) {
        logActivity(null, 'login_failed', "username=$username");
        jsonOut(false, 'Username atau password salah.');
    }
    if ($user['role'] === 'blocked') jsonOut(false, 'Akun Anda telah diblokir. Hubungi administrator.');
    if ($user['role'] === 'trial' && $user['trial_expires_at'] && strtotime($user['trial_expires_at']) < time()) {
        jsonOut(false, 'Masa trial Anda sudah berakhir. Hubungi administrator untuk upgrade.');
    }

    // Device limit check
    $ua         = substr($_SERVER['HTTP_USER_AGENT'] ?? 'unknown', 0, 200);
    $ip         = substr($_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '', 0, 45);
    $deviceHash = hash('sha256', $ua . '|' . substr($ip, 0, strrpos($ip, '.') ?: strlen($ip)));
    $maxDevices = (int)($user['max_devices'] ?? 2);

    $devCheck = $db->prepare("SELECT id FROM fg_user_devices WHERE user_id=? AND device_hash=?");
    $devCheck->execute([$user['id'], $deviceHash]);
    $knownDevice = $devCheck->fetch();

    if (!$knownDevice) {
        $devCount = $db->prepare("SELECT COUNT(*) FROM fg_user_devices WHERE user_id=? AND is_active=1");
        $devCount->execute([$user['id']]);
        $activeDevices = (int)$devCount->fetchColumn();

        if ($activeDevices >= $maxDevices) {
            $devList = $db->prepare("SELECT device_name FROM fg_user_devices WHERE user_id=? AND is_active=1 ORDER BY last_seen DESC");
            $devList->execute([$user['id']]);
            $devNames = array_column($devList->fetchAll(), 'device_name');
            logActivity($user['id'], 'login_blocked_device', "ip=$ip");
            jsonOut(false, "Batas maksimal {$maxDevices} device tercapai. Terdaftar: " . implode(', ', $devNames) . ". Hubungi administrator untuk reset device.");
        }

        $deviceName = parseDeviceName($ua);
        $db->prepare("INSERT INTO fg_user_devices (user_id,device_hash,device_name,ip_address) VALUES (?,?,?,?)
                      ON DUPLICATE KEY UPDATE last_seen=NOW(), is_active=1, ip_address=?")
           ->execute([$user['id'], $deviceHash, $deviceName, $ip, $ip]);
    } else {
        $db->prepare("UPDATE fg_user_devices SET last_seen=NOW(), ip_address=? WHERE user_id=? AND device_hash=?")
           ->execute([$ip, $user['id'], $deviceHash]);
    }

    $db->prepare("UPDATE fg_users SET last_login=NOW(), login_count=login_count+1 WHERE id=?")->execute([$user['id']]);

    session_name(SESSION_NAME);
    session_start();
    if (!empty($_SESSION['user_id'])) {
        if ($_SESSION['user_id'] != $user['id']) {
            session_write_close();
            session_id($_COOKIE[SESSION_NAME] ?? session_create_id());
            session_start();
        }
    }
    $_SESSION['user_id']   = $user['id'];
    $_SESSION['username']  = $user['username'];
    $_SESSION['role']      = $user['role'];
    $_SESSION['full_name'] = $user['full_name'];
    $_SESSION['trial_exp'] = $user['trial_expires_at'];

    logActivity($user['id'], 'login', "role={$user['role']}");
    jsonOut(true, 'Login berhasil.', [
        'role'      => $user['role'],
        'full_name' => $user['full_name'],
        'trial_exp' => $user['trial_expires_at'],
    ]);
}

// ── LOGOUT ────────────────────────────────────────────────────
if ($action === 'logout') {
    session_name(SESSION_NAME);
    session_start();
    $uid = $_SESSION['user_id'] ?? null;
    logActivity($uid, 'logout', '');
    session_unset();
    session_destroy();
    setcookie(SESSION_NAME, '', time()-3600, '/');
    if (!empty($_GET['redirect'])) {
        header('Location: ../index.php');
        exit;
    }
    jsonOut(true, 'Logout berhasil.');
}

// ── REGISTER ──────────────────────────────────────────────────
if ($action === 'register') {
    if (!ALLOW_SELF_REGISTER) jsonOut(false, 'Registrasi mandiri tidak aktif.');

    $username = trim($_POST['username'] ?? '');
    $email    = trim($_POST['email'] ?? '');
    $password = $_POST['password'] ?? '';
    $fullname = trim($_POST['full_name'] ?? '');
    $company  = trim($_POST['company'] ?? '');

    if (!$username || !$email || !$password) jsonOut(false, 'Semua field wajib diisi.');
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) jsonOut(false, 'Format email tidak valid.');
    if (strlen($password) < 8) jsonOut(false, 'Password minimal 8 karakter.');
    if (!preg_match('/^[a-zA-Z0-9_\-]{3,40}$/', $username)) jsonOut(false, 'Username hanya huruf, angka, _ dan - (3-40 karakter).');

    $db  = getDB();
    $chk = $db->prepare("SELECT id FROM fg_users WHERE username=? OR email=? LIMIT 1");
    $chk->execute([$username, $email]);
    if ($chk->fetch()) jsonOut(false, 'Username atau email sudah terdaftar.');

    $hash    = password_hash($password, PASSWORD_DEFAULT);
    $expires = date('Y-m-d H:i:s', time() + TRIAL_DURATION_HOURS * 3600);
    $ins     = $db->prepare("INSERT INTO fg_users (username,email,password_hash,role,full_name,company,trial_expires_at) VALUES (?,?,?,'trial',?,?,?)");
    $ins->execute([$username, $email, $hash, $fullname, $company, $expires]);

    logActivity((int)$db->lastInsertId(), 'register', "email=$email");
    jsonOut(true, 'Registrasi berhasil! Akun trial aktif ' . TRIAL_DURATION_HOURS . ' jam.');
}

// ── CHECK SESSION ─────────────────────────────────────────────
if ($action === 'check') {
    session_name(SESSION_NAME);
    session_start();
    if (!empty($_SESSION['user_id'])) {
        jsonOut(true, 'Authenticated', [
            'role'      => $_SESSION['role'],
            'full_name' => $_SESSION['full_name'],
            'trial_exp' => $_SESSION['trial_exp'] ?? null,
        ]);
    }
    jsonOut(false, 'Not authenticated');
}

jsonOut(false, 'Aksi tidak dikenal.');
