<?php
/**
 * Mastreams PHP Admin — Node.js API Client
 * All data flows through the Node.js REST API.
 * PHP admin never connects to PostgreSQL directly.
 */

define('API_BASE', getenv('MASTREAMS_API_URL') ?: 'http://localhost:3000/api');
define('API_TIMEOUT', 15);

/**
 * Get admin JWT from session
 */
function getAdminToken(): ?string {
    return $_SESSION['admin_token'] ?? null;
}

/**
 * Core cURL request to Node.js API
 */
function apiRequest(string $method, string $path, array $body = [], bool $auth = true): array {
    $url = API_BASE . $path;
    $ch = curl_init($url);

    $headers = ['Content-Type: application/json', 'Accept: application/json'];
    if ($auth && getAdminToken()) {
        $headers[] = 'Authorization: Bearer ' . getAdminToken();
    }

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => API_TIMEOUT,
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_SSL_VERIFYPEER => true,
    ]);

    if ($method === 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    } elseif ($method === 'PATCH') {
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    } elseif ($method === 'DELETE') {
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
    }

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error    = curl_error($ch);
    curl_close($ch);

    if ($error) {
        return ['success' => false, 'message' => 'API connection failed: ' . $error, 'http_code' => 0];
    }

    $data = json_decode($response, true) ?? [];
    $data['http_code'] = $httpCode;
    return $data;
}

function apiGet(string $path, array $params = []): array {
    $query = $params ? '?' . http_build_query($params) : '';
    return apiRequest('GET', $path . $query);
}

function apiPost(string $path, array $body = []): array {
    return apiRequest('POST', $path, $body);
}

function apiPatch(string $path, array $body = []): array {
    return apiRequest('PATCH', $path, $body);
}

function apiDelete(string $path): array {
    return apiRequest('DELETE', $path);
}

/**
 * Upload files to Node.js which then pushes to R2
 * Uses multipart/form-data
 */
function apiUploadFiles(string $movieId, array $files): array {
    $url = API_BASE . '/upload/movie-media/' . $movieId;
    $token = getAdminToken();

    $ch = curl_init($url);
    $postFields = [];

    foreach ($files as $fieldName => $tmpPath) {
        if (!empty($tmpPath) && file_exists($tmpPath)) {
            $postFields[$fieldName] = new CURLFile($tmpPath);
        }
    }

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $postFields,
        CURLOPT_TIMEOUT        => 300, // 5 min for video upload
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $token,
            'Accept: application/json',
            // Note: NO Content-Type header — curl sets multipart/form-data automatically
        ],
    ]);

    $response = curl_exec($ch);
    $error    = curl_error($ch);
    curl_close($ch);

    if ($error) {
        return ['success' => false, 'message' => 'Upload failed: ' . $error];
    }
    return json_decode($response, true) ?? ['success' => false, 'message' => 'Invalid response'];
}

/**
 * Get a presigned R2 URL for large video uploads
 * (Flutter/browser uploads directly to R2, bypassing Node.js for large files)
 */
function getPresignedVideoUrl(string $movieId, string $filename, string $contentType): array {
    return apiPost('/upload/presigned-video-url', [
        'movieId'     => $movieId,
        'filename'    => $filename,
        'contentType' => $contentType,
    ]);
}

// ─── Convenience wrappers ─────────────────────────────────────

function getDashboardStats(): array {
    $data = apiGet('/admin/stats');
    return $data['success'] ? $data : ['stats' => [], 'recentPayments' => []];
}

function getMovies(array $params = []): array {
    $data = apiGet('/movies', $params);
    return $data['movies'] ?? [];
}

function getMovie(string $id): array {
    $data = apiGet('/movies/' . $id);
    return $data['movie'] ?? [];
}

function createMovie(array $fields): array {
    return apiPost('/movies', $fields);
}

function updateMovie(string $id, array $fields): array {
    return apiPatch('/movies/' . $id, $fields);
}

function deleteMovie(string $id): array {
    return apiDelete('/movies/' . $id);
}

function getUsers(array $params = []): array {
    $data = apiGet('/users', $params);
    return $data['users'] ?? [];
}

function updateUserStatus(string $userId, string $status): array {
    return apiPatch('/users/' . $userId . '/status', ['status' => $status]);
}

function getPayments(array $params = []): array {
    $data = apiGet('/payments', $params);
    return $data['payments'] ?? [];
}

function getCategories(): array {
    $data = apiGet('/categories');
    return $data['categories'] ?? [];
}

function createCategory(string $name, string $slug, int $order = 0): array {
    return apiPost('/categories', ['name' => $name, 'slug' => $slug, 'display_order' => $order]);
}

function updateCategory(string $id, array $fields): array {
    return apiPatch('/categories/' . $id, $fields);
}

function deleteCategory(string $id): array {
    return apiDelete('/categories/' . $id);
}
