<?php
/* ============================================================================
 *  gdrive_lib.php — minimal Google Drive helper (no Composer).
 *  gd_upload(name, tmpPath, mime) uploads a file to your Drive and returns
 *  ['ok'=>bool, 'id'=>, 'link'=>, 'error'=>].
 * ==========================================================================*/

function gd_cfg(): array { return require __DIR__ . '/gdrive_config.php'; }

/* exchange the refresh token for a short-lived access token (cached per request) */
function gd_access_token(array $cfg): ?string {
    static $cachedTok = null; static $cachedKey = null;
    if (empty($cfg['client_id']) || empty($cfg['client_secret']) || empty($cfg['refresh_token'])) return null;
    $key = $cfg['refresh_token'];
    if ($cachedTok !== null && $cachedKey === $key) return $cachedTok;
    $ch = curl_init('https://oauth2.googleapis.com/token');
    curl_setopt_array($ch, [
        CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15,
        CURLOPT_POSTFIELDS => http_build_query([
            'client_id'     => $cfg['client_id'],
            'client_secret' => $cfg['client_secret'],
            'refresh_token' => $cfg['refresh_token'],
            'grant_type'    => 'refresh_token',
        ]),
    ]);
    $res = curl_exec($ch); curl_close($ch);
    $d = json_decode((string)$res, true);
    $cachedKey = $key;
    return $cachedTok = ($d['access_token'] ?? null);
}

/* upload a local file to Drive (multipart). Returns id + shareable-ish link. */
function gd_upload(string $name, string $tmpPath, string $mime = 'application/octet-stream'): array {
    $cfg = gd_cfg();
    $token = gd_access_token($cfg);
    if (!$token) return ['ok'=>false, 'error'=>'Could not get access token — check client_id/secret/refresh_token.'];
    if (!is_readable($tmpPath)) return ['ok'=>false, 'error'=>'File not readable on server.'];

    $meta = ['name' => $name];
    $folderId = !empty($cfg['folder_id']) ? $cfg['folder_id'] : gd_folder_id($cfg['folder_name'] ?? 'Service Portal Job Photos', $token);
    if ($folderId) $meta['parents'] = [$folderId];

    $boundary = 'sd' . bin2hex(random_bytes(8));
    $body  = "--$boundary\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n" . json_encode($meta) . "\r\n";
    $body .= "--$boundary\r\nContent-Type: $mime\r\n\r\n" . file_get_contents($tmpPath) . "\r\n--$boundary--";

    $ch = curl_init('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,webViewLink,webContentLink');
    curl_setopt_array($ch, [
        CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $token,
            'Content-Type: multipart/related; boundary=' . $boundary,
        ],
        CURLOPT_POSTFIELDS => $body,
    ]);
    $res  = curl_exec($ch);
    $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    $d = json_decode((string)$res, true);

    if ($code >= 200 && $code < 300 && !empty($d['id'])) {
        return ['ok'=>true, 'id'=>$d['id'], 'name'=>$d['name'] ?? $name,
                'link'=>$d['webViewLink'] ?? ('https://drive.google.com/file/d/'.$d['id'].'/view')];
    }
    return ['ok'=>false, 'error'=>'Upload failed ('.$code.'): '.((isset($d['error']['message'])?$d['error']['message']:$res))];
}

/* find (or create) a Drive folder by name; returns its id or ''. Cached per request. */
function gd_folder_id(string $name, ?string $token = null): string {
    static $cache = [];
    if (isset($cache[$name])) return $cache[$name];
    if (!$token) { $token = gd_access_token(gd_cfg()); if (!$token) return $cache[$name] = ''; }

    /* search among files this app created (drive.file scope) */
    $q = "mimeType='application/vnd.google-apps.folder' and name='" . str_replace("'", "\\'", $name) . "' and trashed=false";
    $url = 'https://www.googleapis.com/drive/v3/files?' . http_build_query([
        'q' => $q, 'fields' => 'files(id,name)', 'spaces' => 'drive', 'pageSize' => 1,
    ]);
    $ch = curl_init($url);
    curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>15, CURLOPT_HTTPHEADER=>['Authorization: Bearer '.$token]]);
    $res = curl_exec($ch); curl_close($ch);
    $d = json_decode((string)$res, true);
    if (!empty($d['files'][0]['id'])) return $cache[$name] = $d['files'][0]['id'];

    /* not found -> create it */
    $ch = curl_init('https://www.googleapis.com/drive/v3/files?fields=id');
    curl_setopt_array($ch, [
        CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>15,
        CURLOPT_HTTPHEADER=>['Authorization: Bearer '.$token, 'Content-Type: application/json'],
        CURLOPT_POSTFIELDS=>json_encode(['name'=>$name, 'mimeType'=>'application/vnd.google-apps.folder']),
    ]);
    $res = curl_exec($ch); curl_close($ch);
    $d = json_decode((string)$res, true);
    return $cache[$name] = ($d['id'] ?? '');
}

/* download a Drive file's bytes (for the image proxy). Returns ['ok','mime','body']. */
function gd_download(string $id): array {
    $cfg = gd_cfg();
    $token = gd_access_token($cfg);
    if (!$token) return ['ok'=>false];
    $ch = curl_init('https://www.googleapis.com/drive/v3/files/' . rawurlencode($id) . '?alt=media');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
    ]);
    $body = curl_exec($ch);
    $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $mime = curl_getinfo($ch, CURLINFO_CONTENT_TYPE) ?: 'application/octet-stream';
    curl_close($ch);
    if ($code >= 200 && $code < 300) return ['ok'=>true, 'mime'=>$mime, 'body'=>$body];
    return ['ok'=>false, 'code'=>$code];
}

/* delete a Drive file (used when a job/image is removed). */
function gd_delete(string $id): bool {
    $cfg = gd_cfg();
    $token = gd_access_token($cfg);
    if (!$token) return false;
    $ch = curl_init('https://www.googleapis.com/drive/v3/files/' . rawurlencode($id));
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
    ]);
    curl_exec($ch);
    $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $code >= 200 && $code < 300;
}

/* extract a Drive file id from a stored image_path like "drive_file.php?id=XXXX", or '' */
function gd_id_from_path(string $path): string {
    if (preg_match('/[?&]id=([A-Za-z0-9_\-]+)/', $path, $m)) return $m[1];
    return '';
}
