<?php

class Auth {
    private const JWT_ALGO = 'HS256';
    private const JWT_EXPIRY = 3600; // 1 hour
    
    private string $usersFile;
    private string $jwtSecret;
    
    public function __construct(string $usersFile = null) {
        $this->usersFile = $usersFile ?? __DIR__ . '/../config/users.json';
        
        // Load JWT secret from environment variable
        $this->jwtSecret = $_ENV['JWT_SECRET'] ?? getenv('JWT_SECRET');
        if (empty($this->jwtSecret)) {
            throw new Exception('JWT_SECRET environment variable is not configured');
        }
    }
    
    public function login(string $username, string $password): array {
        $users = $this->loadUsers();
        
        foreach ($users['users'] as $user) {
            if ($user['username'] === $username) {
                if (password_verify($password, $user['password'])) {
                    $token = $this->generateToken($user);
                    return [
                        'success' => true,
                        'token' => $token,
                        'user' => [
                            'username' => $user['username'],
                            'role' => $user['role']
                        ]
                    ];
                }
                return ['success' => false, 'error' => 'Invalid password'];
            }
        }
        
        return ['success' => false, 'error' => 'User not found'];
    }
    
    public function verifyToken(string $token): ?array {
        $parts = explode('.', $token);
        
        if (count($parts) !== 3) {
            return null;
        }
        
        list($header, $payload, $signature) = $parts;
        
        // Verify signature
        $expectedSignature = base64_encode(
            hash_hmac('sha256', "$header.$payload", $this->jwtSecret, true)
        );
        
        if (!hash_equals($expectedSignature, $signature)) {
            return null;
        }
        
        // Decode payload
        $payloadData = json_decode(base64_decode($payload), true);
        
        // Check expiry
        if (isset($payloadData['exp']) && $payloadData['exp'] < time()) {
            return null;
        }
        
        return $payloadData;
    }
    
    public function requireAuth(string $token): array {
        $payload = $this->verifyToken($token);
        
        if ($payload === null) {
            http_response_code(401);
            echo json_encode(['error' => 'Unauthorized']);
            exit;
        }
        
        return $payload;
    }
    
    public function requireAdmin(string $token): array {
        $payload = $this->requireAuth($token);
        
        if ($payload['role'] !== 'admin') {
            http_response_code(403);
            echo json_encode(['error' => 'Forbidden']);
            exit;
        }
        
        return $payload;
    }
    
    private function generateToken(array $user): string {
        $header = base64_encode(json_encode([
            'alg' => self::JWT_ALGO,
            'typ' => 'JWT'
        ]));
        
        $payload = base64_encode(json_encode([
            'username' => $user['username'],
            'role' => $user['role'],
            'iat' => time(),
            'exp' => time() + self::JWT_EXPIRY
        ]));
        
        $signature = base64_encode(
            hash_hmac('sha256', "$header.$payload", $this->jwtSecret, true)
        );
        
        return "$header.$payload.$signature";
    }
    
    private function loadUsers(): array {
        if (!file_exists($this->usersFile)) {
            return ['users' => []];
        }
        
        $content = file_get_contents($this->usersFile);
        return json_decode($content, true) ?? ['users' => []];
    }
    
    public function hashPassword(string $password): string {
        return password_hash($password, PASSWORD_BCRYPT);
    }
}
