<?php
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/../config.php';

class Auth {

    /** Get token from request (GET, POST, or header) */
    public static function getToken(): string {
        return $_GET['token'] ?? $_POST['token'] ?? ($_SERVER['HTTP_X_TOKEN'] ?? '');
    }

    /** Validate token — returns user row or null */
    public static function validateToken(string $token): ?array {
        if (!$token || strlen($token) < 32) return null;
        $db = DB::get();
        $row = $db->selectOne(
            "SELECT t.*, u.username, u.email, u.rights, u.record_id as user_id
             FROM tokens t
             JOIN proart_accounting_users u ON u.record_id = t.user_id
             WHERE t.token = ? AND t.expires_at > NOW() AND t.active = 1",
            's', $token
        );
        return $row ?: null;
    }

    /** Require valid token - dies with JSON error if invalid */
    public static function requireToken(): array {
        $token = self::getToken();
        $user = self::validateToken($token);
        if (!$user) {
            http_response_code(401);
            die(json_encode(['success' => false, 'error' => 'UNAUTHORIZED', 'redirect' => 'login']));
        }
        return $user;
    }

    /** Create a new token for a user */
    public static function createToken(int $userId): string {
        $db = DB::get();
        $token = bin2hex(random_bytes(32));
        $expires = date('Y-m-d H:i:s', strtotime('+' . TOKEN_EXPIRY_HOURS . ' hours'));
        // Deactivate old tokens
        $db->execute("UPDATE tokens SET active = 0 WHERE user_id = ?", 'i', $userId);
        // Insert new token
        $db->execute(
            "INSERT INTO tokens (token, user_id, expires_at, created_at, active) VALUES (?, ?, ?, NOW(), 1)",
            'sis', $token, $userId, $expires
        );
        return $token;
    }

    /** Invalidate a token (logout) */
    public static function revokeToken(string $token): void {
        $db = DB::get();
        $db->execute("UPDATE tokens SET active = 0 WHERE token = ?", 's', $token);
    }

    /** Log an action */
    public static function log(int $userId, string $log, string $table = '', int $recordId = 0): void {
        try {
            $db = DB::get();
            $date = date('Y-m-d H:i:s');
            $db->execute(
                "INSERT INTO logs (proart_accounting_users_id, log, date_time, table_name, affected_record) VALUES (?, ?, ?, ?, ?)",
                'isssi', $userId, strtoupper($log), $date, $table, $recordId
            );
        } catch (Exception $e) { /* non-fatal */ }
    }
}
