<?php

/**
 * Kelas untuk menangani fungsi SecureAuth Authenticator
 */
class SecureAuth_Authenticator {

    /**
     * Panjang kunci rahasia
     */
    protected $secret_length = 16;

    /**
     * Karakter yang digunakan untuk kunci rahasia
     */
    protected $secret_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

    /**
     * Konstruktor
     */
    public function __construct() {
        // Tidak ada yang perlu diinisialisasi
    }

    /**
     * Membuat kunci rahasia baru
     *
     * @return string
     */
    public function createSecret() {
        $secret = '';
        $chars_length = strlen($this->secret_chars);

        for ($i = 0; $i < $this->secret_length; $i++) {
            $secret .= $this->secret_chars[wp_rand(0, $chars_length - 1)];
        }

        return $secret;
    }

    /**
     * Membuat URL QR Code untuk SecureAuth Authenticator
     *
     * @param string $name Nama akun
     * @param string $secret Kunci rahasia
     * @return string URL QR Code
     */

     public function generate_inline_qr_svg($data) {
        // Sangat sederhana placeholder, bukan generator asli
        // Idealnya kamu gunakan QR encoding logic lalu generate SVG    
        $escaped_data = htmlspecialchars($data, ENT_QUOTES);
        return '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><text x="10" y="20">QR: ' . $escaped_data . '</text></svg>';
    }
    
    
    public function getQRCodeGoogleUrl($name, $secret) {
        $site_name = get_bloginfo('name');
        $label = "{$site_name}:{$name}";
        $otpauth = "otpauth://totp/{$label}?secret={$secret}&issuer={$site_name}";
        $encoded = urlencode($otpauth);
        return "https://api.qrserver.com/v1/create-qr-code/?size=200x200&data={$encoded}";
    }
    
    

    /**
     * Verifikasi kode TOTP dari aplikasi Authenticator
     *
     * @param string $secret Secret key
     * @param string $code   Kode dari user
     * @return bool
     */
    public function verify_code($secret, $code) {
        $secretKey = $this->base32_decode($secret);
        $timestamp = floor(time() / 30);
        
        // Cek dalam rentang waktu ±1 (toleransi)
        for ($i = -1; $i <= 1; $i++) {
            $calculated = $this->generate_totp($secretKey, $timestamp + $i);
            if ($calculated === $code) {
                return true;
            }
        }

        return false;
    }

    /**
     * Generate TOTP berdasarkan secret dan timestamp
     */
    private function generate_totp($key, $timestamp) {
        $binTime = pack('N*', 0) . pack('N*', $timestamp);
        $hash = hash_hmac('sha1', $binTime, $key, true);
        $offset = ord(substr($hash, -1)) & 0x0F;
        $truncatedHash = unpack('N', substr($hash, $offset, 4))[1] & 0x7FFFFFFF;
        return str_pad($truncatedHash % 1000000, 6, '0', STR_PAD_LEFT);
    }

    /**
     * Decode Base32 string (karena aplikasi authenticator pakai base32)
     */
    private function base32_decode($input) {
        $map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
        $input = strtoupper($input);
        $binaryString = '';
        for ($i = 0; $i < strlen($input); $i++) {
            $currentChar = $input[$i];
            $currentCharPos = strpos($map, $currentChar);
            if ($currentCharPos === false) {
                continue;
            }
            $binaryString .= str_pad(decbin($currentCharPos), 5, '0', STR_PAD_LEFT);
        }
        $eightBits = str_split($binaryString, 8);
        $decoded = '';
        foreach ($eightBits as $bits) {
            if (strlen($bits) < 8) {
                continue;
            }
            $decoded .= chr(bindec($bits));
        }
        return $decoded;
    }

}