<?php
/**
 * Google Drive Helper - 使用 cURL 直接呼叫 Google Drive API v3
 * 無需安裝 Composer 或 Google SDK
 */

class GoogleDriveHelper {
    private $pdo;
    private $accessToken;
    private $folderId;
    private $cacheTTL = 60; // 快取 60 秒

    public function __construct($pdo) {
        $this->pdo = $pdo;
        $this->ensureTokenTable();
        $this->loadAccessToken();
    }

    // 確保 token 表存在
    private function ensureTokenTable() {
        $this->pdo->exec("CREATE TABLE IF NOT EXISTS google_drive_tokens (
            id INT AUTO_INCREMENT PRIMARY KEY,
            access_token TEXT,
            refresh_token TEXT,
            expires_at DATETIME,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )");
        $this->pdo->exec("CREATE TABLE IF NOT EXISTS google_drive_cache (
            cache_key VARCHAR(255) PRIMARY KEY,
            cache_value LONGTEXT,
            expires_at BIGINT
        )");
    }

    // 從快取讀取
    private function cacheGet($key) {
        $stmt = $this->pdo->prepare("SELECT cache_value FROM google_drive_cache WHERE cache_key = ? AND expires_at > ?");
        $stmt->execute([$key, time()]);
        $row = $stmt->fetch();
        return $row ? json_decode($row['cache_value'], true) : null;
    }

    // 寫入快取
    private function cacheSet($key, $value, $ttl = null) {
        $ttl = $ttl ?: $this->cacheTTL;
        $stmt = $this->pdo->prepare("REPLACE INTO google_drive_cache (cache_key, cache_value, expires_at) VALUES (?, ?, ?)");
        $stmt->execute([$key, json_encode($value), time() + $ttl]);
    }

    // 從資料庫載入 token
    private function loadAccessToken() {
        $stmt = $this->pdo->query("SELECT * FROM google_drive_tokens ORDER BY id DESC LIMIT 1");
        $token = $stmt->fetch();

        if (!$token) {
            $this->accessToken = null;
            return;
        }

        // 如果 token 過期，嘗試刷新
        if (strtotime($token['expires_at']) < time()) {
            $this->refreshAccessToken($token['refresh_token']);
        } else {
            $this->accessToken = $token['access_token'];
        }
    }

    // 刷新 access token
    private function refreshAccessToken($refreshToken) {
        if (empty(GOOGLE_DRIVE_CLIENT_ID_DB) || empty(GOOGLE_DRIVE_CLIENT_SECRET_DB)) return;

        $ch = curl_init('https://oauth2.googleapis.com/token');
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query([
                'client_id' => GOOGLE_DRIVE_CLIENT_ID_DB,
                'client_secret' => GOOGLE_DRIVE_CLIENT_SECRET_DB,
                'refresh_token' => $refreshToken,
                'grant_type' => 'refresh_token'
            ]),
            CURLOPT_RETURNTRANSFER => true
        ]);
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($http_code === 200) {
            $data = json_decode($response, true);
            $this->accessToken = $data['access_token'];
            $expires_at = date('Y-m-d H:i:s', time() + $data['expires_in']);

            $stmt = $this->pdo->prepare("INSERT INTO google_drive_tokens (access_token, refresh_token, expires_at) VALUES (?, ?, ?)");
            $stmt->execute([$this->accessToken, $refreshToken, $expires_at]);
        }
    }

    // 儲存初次授權的 token
    public function saveTokens($accessToken, $refreshToken, $expiresIn) {
        $expires_at = date('Y-m-d H:i:s', time() + $expiresIn);
        $this->pdo->exec("DELETE FROM google_drive_tokens");
        $stmt = $this->pdo->prepare("INSERT INTO google_drive_tokens (access_token, refresh_token, expires_at) VALUES (?, ?, ?)");
        $stmt->execute([$accessToken, $refreshToken, $expires_at]);
        $this->accessToken = $accessToken;
    }

    // 檢查是否已認證
    public function isAuthenticated() {
        return !empty($this->accessToken);
    }

    // 建立或取得應用程式資料夾
    public function getOrCreateAppFolder() {
        if (!$this->isAuthenticated()) return null;
        if ($this->folderId) return $this->folderId;

        // 先搜尋是否已有資料夾
        $result = $this->apiRequest('GET', 'https://www.googleapis.com/drive/v3/files', [
            'q' => "name='" . GOOGLE_DRIVE_FOLDER_NAME . "' and mimeType='application/vnd.google-apps.folder' and trashed=false",
            'fields' => 'files(id, name)',
            'pageSize' => 1
        ]);

        if (!empty($result['files'])) {
            $this->folderId = $result['files'][0]['id'];
            return $this->folderId;
        }

        // 建立新資料夾
        $result = $this->apiRequest('POST', 'https://www.googleapis.com/drive/v3/files', null, [
            'name' => GOOGLE_DRIVE_FOLDER_NAME,
            'mimeType' => 'application/vnd.google-apps.folder'
        ]);

        if ($result && isset($result['id'])) {
            $this->folderId = $result['id'];
            return $this->folderId;
        }

        return null;
    }

    // 在地盤資料夾下建立子資料夾
    public function ensureSiteFolder($siteName) {
        $appFolderId = $this->getOrCreateAppFolder();
        if (!$appFolderId) return null;

        $result = $this->apiRequest('GET', 'https://www.googleapis.com/drive/v3/files', [
            'q' => "name='" . addslashes($siteName) . "' and '" . $appFolderId . "' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false",
            'fields' => 'files(id, name)',
            'pageSize' => 1
        ]);

        if (!empty($result['files'])) {
            return $result['files'][0]['id'];
        }

        $result = $this->apiRequest('POST', 'https://www.googleapis.com/drive/v3/files', null, [
            'name' => $siteName,
            'mimeType' => 'application/vnd.google-apps.folder',
            'parents' => [$appFolderId]
        ]);

        return $result['id'] ?? null;
    }

    // 上傳檔案到 Google Drive
    public function uploadFile($filePath, $fileName, $mimeType, $parentFolderId) {
        if (!$this->isAuthenticated()) return null;

        $boundary = uniqid();
        $payload = "--{$boundary}\r\n";
        $payload .= "Content-Type: application/json; charset=UTF-8\r\n\r\n";
        $payload .= json_encode([
            'name' => $fileName,
            'parents' => [$parentFolderId]
        ]) . "\r\n";
        $payload .= "--{$boundary}\r\n";
        $payload .= "Content-Type: {$mimeType}\r\n\r\n";
        $payload .= file_get_contents($filePath) . "\r\n";
        $payload .= "--{$boundary}--";

        $ch = curl_init('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart');
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Authorization: Bearer ' . $this->accessToken,
                'Content-Type: multipart/related; boundary=' . $boundary,
                'Content-Length: ' . strlen($payload)
            ],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true
        ]);
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($http_code === 200) {
            return json_decode($response, true);
        }
        return null;
    }

    // 從 Google Drive 下載檔案
    public function downloadFile($fileId) {
        if (!$this->isAuthenticated()) return null;

        $ch = curl_init("https://www.googleapis.com/drive/v3/files/{$fileId}?alt=media");
        curl_setopt_array($ch, [
            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $this->accessToken],
            CURLOPT_RETURNTRANSFER => true
        ]);
        $content = curl_exec($ch);
        curl_close($ch);

        return $content;
    }

    // 獲取檔案分享連結
    public function getFileLink($fileId) {
        if (!$this->isAuthenticated()) return null;

        // 設定檔案權限為 anyone with link can view
        $this->apiRequest('POST', "https://www.googleapis.com/drive/v3/files/{$fileId}/permissions", null, [
            'type' => 'anyone',
            'role' => 'reader'
        ]);

        $file = $this->apiRequest('GET', "https://www.googleapis.com/drive/v3/files/{$fileId}", [
            'fields' => 'webViewLink,webContentLink'
        ]);

        return $file['webViewLink'] ?? null;
    }

    // 刪除檔案
    public function deleteFile($fileId) {
        if (!$this->isAuthenticated()) return;

        $ch = curl_init("https://www.googleapis.com/drive/v3/files/{$fileId}");
        curl_setopt_array($ch, [
            CURLOPT_CUSTOMREQUEST => 'DELETE',
            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $this->accessToken],
            CURLOPT_RETURNTRANSFER => true
        ]);
        curl_exec($ch);
        curl_close($ch);
    }

    // 在資料夾下建立子資料夾（Google Drive 上）
    public function createFolder($folderName, $parentFolderId) {
        if (!$this->isAuthenticated()) return null;

        $result = $this->apiRequest('POST', 'https://www.googleapis.com/drive/v3/files', null, [
            'name' => $folderName,
            'mimeType' => 'application/vnd.google-apps.folder',
            'parents' => [$parentFolderId]
        ]);

        return $result['id'] ?? null;
    }

    // 通用 API 請求
    private function apiRequest($method, $url, $params = null, $body = null) {
        if ($params) {
            $url .= '?' . http_build_query($params);
        }

        $ch = curl_init($url);
        $options = [
            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $this->accessToken, 'Content-Type: application/json'],
            CURLOPT_RETURNTRANSFER => true
        ];

        if ($method === 'POST') {
            $options[CURLOPT_POST] = true;
            if ($body) {
                $options[CURLOPT_POSTFIELDS] = json_encode($body);
            }
        } elseif ($method === 'DELETE') {
            $options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
        }

        curl_setopt_array($ch, $options);
        $response = curl_exec($ch);
        curl_close($ch);

        return json_decode($response, true);
    }

    // ===== 新增：列出 Google Drive 資料夾內容 =====

    // 列出資料夾內的所有內容（檔案+子資料夾）
    public function listFolderContents($folderId) {
        if (!$this->isAuthenticated()) return ['files' => [], 'folders' => []];

        // 嘗試從快取讀取
        $cacheKey = 'contents_' . $folderId;
        $cached = $this->cacheGet($cacheKey);
        if ($cached) return $cached;

        $q = "'{$folderId}' in parents and trashed=false";
        $result = $this->apiRequest('GET', 'https://www.googleapis.com/drive/v3/files', [
            'q' => $q,
            'fields' => 'files(id, name, mimeType, size, webViewLink, thumbnailLink, createdTime, modifiedTime, iconLink)',
            'pageSize' => 500,
            'orderBy' => 'folder,name'
        ]);

        $files = [];
        $folders = [];
        
        if (!empty($result['files'])) {
            foreach ($result['files'] as $f) {
                $entry = [
                    'id' => $f['id'],
                    'name' => $f['name'],
                    'mimeType' => $f['mimeType'],
                    'webViewLink' => $f['webViewLink'] ?? '',
                    'thumbnailLink' => $f['thumbnailLink'] ?? '',
                    'iconLink' => $f['iconLink'] ?? '',
                    'size' => (int)($f['size'] ?? 0),
                    'createdTime' => $f['createdTime'] ?? '',
                    'modifiedTime' => $f['modifiedTime'] ?? ''
                ];
                
                if ($f['mimeType'] === 'application/vnd.google-apps.folder') {
                    $folders[] = $entry;
                } else {
                    $entry['fileExtension'] = pathinfo($f['name'], PATHINFO_EXTENSION);
                    $files[] = $entry;
                }
            }
        }

        $result = ['files' => $files, 'folders' => $folders];
        $this->cacheSet($cacheKey, $result, 60);
        return $result;
    }

    // 取得單一檔案/資料夾資訊
    public function getFileInfo($fileId) {
        if (!$this->isAuthenticated()) return null;

        return $this->apiRequest('GET', "https://www.googleapis.com/drive/v3/files/{$fileId}", [
            'fields' => 'id, name, mimeType, parents, webViewLink, thumbnailLink, size, createdTime, modifiedTime'
        ]);
    }

    // 取得資料夾的上層路徑（用於麵包屑導航）
    public function getFolderPath($folderId) {
        if (!$this->isAuthenticated()) return [];

        $cacheKey = 'path_' . $folderId;
        $cached = $this->cacheGet($cacheKey);
        if ($cached) return $cached;

        $path = [];
        $currentId = $folderId;
        $maxDepth = 20;
        $depth = 0;

        while ($currentId && $depth < $maxDepth) {
            // 每層也快取，避免重複請求
            $infoCacheKey = 'fileinfo_' . $currentId;
            $info = $this->cacheGet($infoCacheKey);
            if (!$info) {
                $info = $this->getFileInfo($currentId);
                if ($info) $this->cacheSet($infoCacheKey, $info, 120);
            }
            if (!$info) break;

            array_unshift($path, [
                'id' => $info['id'],
                'name' => $info['name']
            ]);

            if (!empty($info['parents'])) {
                $currentId = $info['parents'][0];
            } else {
                break;
            }
            $depth++;
        }

        $this->cacheSet($cacheKey, $path, 120);
        return $path;
    }

    // 產生 OAuth URL
    public static function getAuthUrl() {
        $params = http_build_query([
            'client_id' => GOOGLE_DRIVE_CLIENT_ID_DB,
            'redirect_uri' => GOOGLE_DRIVE_REDIRECT_URI,
            'response_type' => 'code',
            'scope' => 'https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata.readonly',
            'access_type' => 'offline',
            'prompt' => 'consent'
        ]);
        return 'https://accounts.google.com/o/oauth2/v2/auth?' . $params;
    }
}
