<?php
/**
 * Class GoogleDrive
 * Upload file ke Google Drive menggunakan Google API PHP Client (manual folder)
 * Dioptimalkan untuk theme Appyn / situs download APK
 */

use Google\Client as Google_Client;
use Google\Service\Drive as Google_Service_Drive;
use Google\Service\Drive\DriveFile as Google_Service_Drive_DriveFile;
use Google\Service\Drive\Permission as Google_Service_Drive_Permission;

class GoogleDrive {

    /**
     * Mendapatkan Google Client yang sudah ter-autentikasi
     *
     * @return Google_Client|false
     */
    public function getClient() {
        global $opt_themes;

        $client_id     = isset($opt_themes['gdrive_client_id']) ? trim($opt_themes['gdrive_client_id']) : '';
        $client_secret = isset($opt_themes['gdrive_client_secret']) ? trim($opt_themes['gdrive_client_secret']) : '';

        if (empty($client_id) || empty($client_secret)) {
            return false;
        }

        // Path ke autoload.php dari folder manual google-api-php-client-master
        $autoload_path = get_template_directory() . '/libs/addons/google-api-php-client-master/vendor/autoload.php';

        if (!file_exists($autoload_path)) {
            error_log('GoogleDrive: autoload.php tidak ditemukan di ' . $autoload_path);
            return false;
        }

        require_once $autoload_path;

        $client = new Google_Client();
        $client->setClientId($client_id);
        $client->setClientSecret($client_secret);
        
        // Redirect URI harus sesuai dengan yang ada di Google Cloud Console
        $client->setRedirectUri(admin_url('admin.php?page=_options&tab=22'));
        
        $client->addScope(Google_Service_Drive::DRIVE); // Full access untuk upload & share
        $client->setAccessType('offline');              // Penting untuk mendapatkan refresh token
        $client->setPrompt('consent');                  // Force approval screen agar refresh token diberikan

        // Load token yang tersimpan
        $saved_token = get_option('appyn_gdrive_token');
        if ($saved_token) {
            $accessToken = json_decode($saved_token, true);
            if ($accessToken) {
                $client->setAccessToken($accessToken);
            }
        }

        // Refresh token jika sudah expired
        if ($client->isAccessTokenExpired()) {
            if ($client->getRefreshToken()) {
                $newToken = $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
                if (!isset($newToken['error'])) {
                    update_option('appyn_gdrive_token', json_encode($newToken));
                } else {
                    error_log('GoogleDrive Refresh Token Error: ' . print_r($newToken, true));
                    return false;
                }
            } else {
                // Tidak ada refresh token → perlu otorisasi ulang
                return false;
            }
        }

        return $client;
    }

    /**
     * Upload file ke Google Drive dan kembalikan direct download link
     *
     * @param string $file_path       Full path ke file di server
     * @param string $file_name       Nama file di Google Drive
     * @param string|null $parent_folder_id Opsional: ID folder tujuan
     * @return array ['url' => direct_link] atau ['error' => message]
     */
    public function insertFileToDrive($file_path, $file_name, $parent_folder_id = null) {
        // Validasi file
        if (!file_exists($file_path)) {
            return ['error' => 'File tidak ditemukan: ' . basename($file_path)];
        }
        if (!is_readable($file_path)) {
            return ['error' => 'File tidak bisa dibaca: ' . basename($file_path)];
        }

        $client = $this->getClient();
        if (!$client) {
            return ['error' => 'Kredensial Google Drive belum diatur atau token tidak valid. Silakan lakukan otorisasi ulang di pengaturan tema.'];
        }

        $service = new Google_Service_Drive($client);

        $file = new Google_Service_Drive_DriveFile();
        $file->setName($file_name);

        if ($parent_folder_id && strlen($parent_folder_id) === 33) { // Validasi sederhana ID folder
            $file->setParents([$parent_folder_id]);
        }

        // Detect MIME type
        $mimeType = mime_content_type($file_path);
        if (!$mimeType || $mimeType === 'application/octet-stream') {
            // Fallback untuk ekstensi umum
            $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
            $mimeMap = [
                'apk'  => 'application/vnd.android.package-archive',
                'zip'  => 'application/zip',
                'xapk' => 'application/zip',
                'obb'  => 'application/octet-stream',
                'rar'  => 'application/vnd.rar',
                'pdf'  => 'application/pdf',
            ];
            $mimeType = $mimeMap[$ext] ?? 'application/octet-stream';
        }

        try {
            // Upload file
            $createdFile = $service->files->create($file, [
                'data'       => file_get_contents($file_path),
                'mimeType'   => $mimeType,
                'uploadType' => 'multipart',
                'fields'     => 'id,name,size'
            ]);

            // Set permission: anyone with link can view/download
            $permission = new Google_Service_Drive_Permission();
            $permission->setType('anyone');
            $permission->setRole('reader');
            $service->permissions->create($createdFile->id, $permission, ['fields' => 'id']);

            // Direct download link (paling reliable untuk file APK/ZIP/OBB)
            $direct_link = 'https://drive.google.com/uc?export=download&id=' . $createdFile->id;

            return ['url' => $direct_link];
        } catch (Exception $e) {
            $errorMsg = $e->getMessage();
            $decoded  = json_decode($errorMsg, true);
            $message  = $decoded['error']['message'] ?? $errorMsg;

            // Log error untuk debugging
            error_log('GoogleDrive Upload Error: ' . $message);

            return ['error' => 'Upload gagal: ' . $message];
        }
    }

    /**
     * Optional: Cek status koneksi (untuk ditampilkan di pengaturan)
     */
    public function isConnected() {
        $client = $this->getClient();
        return $client && !$client->isAccessTokenExpired() && $client->getRefreshToken();
    }
}