<?php
if (!defined('ABSPATH')) {
    exit;
}

class Foxblock_Backup_Google_OAuth_Handler
{
    private $client_id;
    private $client_secret;
    private $client;

    public function __construct()
    {
        $this->client_id = get_option('foxblock_gdrive_client_id', '');
        $this->client_secret = get_option('foxblock_gdrive_client_secret', '');
        
        $this->init_client();
    }

    private function init_client()
    {
        if (!class_exists('Google\Client')) {
            $autoload = FOXBLOCK_PLUGIN_DIR . 'vendor/autoload.php';
            if (file_exists($autoload)) {
                require_once $autoload;
            }
        }

        if (class_exists('Google\Client')) {
            $this->client = new \Google\Client();
            $this->client->setClientId($this->client_id);
            $this->client->setClientSecret($this->client_secret);
            $this->client->setRedirectUri($this->get_redirect_uri());
            $this->client->addScope(\Google\Service\Drive::DRIVE_FILE);
            $this->client->setAccessType('offline'); 
            $this->client->setPrompt('select_account consent');
            
            $token_data = $this->get_token();
            if ($token_data) {
                $this->client->setAccessToken($token_data);
                
                if ($this->client->isAccessTokenExpired()) {
                    if ($this->client->getRefreshToken()) {
                        $this->client->fetchAccessTokenWithRefreshToken($this->client->getRefreshToken());
                        $new_token = $this->client->getAccessToken();
                        if ($new_token && !isset($new_token['error'])) {
                            $this->save_token($new_token);
                        }
                    }
                }
            }
        }
    }

    public function get_client()
    {
        return $this->client;
    }

    public function get_auth_url()
    {
        if (!$this->client || empty($this->client_id) || empty($this->client_secret)) {
            return false;
        }
        return $this->client->createAuthUrl();
    }

    public function handle_callback($code)
    {
        if (!$this->client) {
            return new WP_Error('no_client', 'Google API Client is not initialized.');
        }

        $token = $this->client->fetchAccessTokenWithAuthCode($code);
        
        if (isset($token['error'])) {
            return new WP_Error('oauth_error', $token['error_description'] ?? $token['error']);
        }

        $this->save_token($token);
        
        // Fetch email
        try {
            $service = new \Google\Service\Drive($this->client);
            $about = $service->about->get(['fields' => 'user(emailAddress)']);
            $email = $about->getUser()->getEmailAddress();
            if ($email) {
                update_option('foxblock_gdrive_email', $email);
            }
        } catch (Exception $e) {
            // Silently ignore if cannot fetch email
        }

        return true;
    }

    public function get_token()
    {
        $encrypted = get_option('foxblock_gdrive_token', '');
        if (empty($encrypted)) return false;
        
        $decrypted = self::decrypt_data($encrypted);
        if (!$decrypted) return false;
        
        return json_decode($decrypted, true);
    }

    public function save_token($token_array)
    {
        $json = json_encode($token_array);
        $encrypted = self::encrypt_data($json);
        update_option('foxblock_gdrive_token', $encrypted);
    }

    public function disconnect()
    {
        if ($this->client) {
            $this->client->revokeToken();
        }
        delete_option('foxblock_gdrive_token');
        delete_option('foxblock_gdrive_email');
        delete_option('foxblock_gdrive_folder');
    }

    public function is_connected()
    {
        $token = $this->get_token();
        if (!$token || !isset($token['access_token'])) {
            return false;
        }
        return true;
    }

    public static function get_redirect_uri()
    {
        return admin_url('admin-ajax.php?action=foxblock_gdrive_oauth_callback');
    }

    private static function get_encryption_key()
    {
        return defined('AUTH_KEY') ? AUTH_KEY : 'foxblock_fallback_secret_key';
    }

    private static function encrypt_data($data)
    {
        $key = self::get_encryption_key();
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
        $encrypted = openssl_encrypt($data, 'aes-256-cbc', substr(hash('sha256', $key), 0, 32), 0, $iv);
        return base64_encode($encrypted . '::' . $iv);
    }

    private static function decrypt_data($data)
    {
        $key = self::get_encryption_key();
        $parts = explode('::', base64_decode($data), 2);
        if (count($parts) !== 2) return false;
        return openssl_decrypt($parts[0], 'aes-256-cbc', substr(hash('sha256', $key), 0, 32), 0, $parts[1]);
    }
}
