<?php
namespace Crawl\Services;

/**
 * Google Analytics 4 Data API v1 wrapper.
 * Requires access token from GoogleOAuthService.
 */
class GA4Service
{
    private const API_BASE = 'https://analyticsdata.googleapis.com/v1beta';

    private GoogleOAuthService $oauth;

    public function __construct()
    {
        $this->oauth = new GoogleOAuthService();
    }

    // Returns last-N-days overview: sessions, users, bounce_rate, avg_session_duration
    public function getOverview(int $projectId, string $propertyId, int $days = 30): array
    {
        $token = $this->oauth->getAccessToken($projectId, 'ga4');
        if (!$token) return ['error' => 'not_connected'];

        $body = $this->runReport($token, $propertyId, [
            'metrics'    => [
                ['name' => 'sessions'],
                ['name' => 'totalUsers'],
                ['name' => 'bounceRate'],
                ['name' => 'averageSessionDuration'],
                ['name' => 'screenPageViews'],
            ],
            'dateRanges' => [['startDate' => "{$days}daysAgo", 'endDate' => 'today']],
        ]);

        if (isset($body['error'])) return ['error' => $body['error']['message'] ?? 'API error'];

        $row = $body['rows'][0]['metricValues'] ?? [];
        return [
            'sessions'               => (int)($row[0]['value'] ?? 0),
            'users'                  => (int)($row[1]['value'] ?? 0),
            'bounce_rate'            => round((float)($row[2]['value'] ?? 0) * 100, 1),
            'avg_session_duration'   => round((float)($row[3]['value'] ?? 0)),
            'page_views'             => (int)($row[4]['value'] ?? 0),
        ];
    }

    // Top pages by sessions
    public function getTopPages(int $projectId, string $propertyId, int $days = 30, int $limit = 50): array
    {
        $token = $this->oauth->getAccessToken($projectId, 'ga4');
        if (!$token) return [];

        $body = $this->runReport($token, $propertyId, [
            'dimensions' => [['name' => 'pagePath']],
            'metrics'    => [
                ['name' => 'sessions'],
                ['name' => 'screenPageViews'],
                ['name' => 'bounceRate'],
                ['name' => 'averageSessionDuration'],
            ],
            'dateRanges' => [['startDate' => "{$days}daysAgo", 'endDate' => 'today']],
            'limit'      => $limit,
            'orderBys'   => [['metric' => ['metricName' => 'sessions'], 'desc' => true]],
        ]);

        $rows = [];
        foreach ($body['rows'] ?? [] as $row) {
            $rows[] = [
                'path'                 => $row['dimensionValues'][0]['value'] ?? '',
                'sessions'             => (int)($row['metricValues'][0]['value'] ?? 0),
                'page_views'           => (int)($row['metricValues'][1]['value'] ?? 0),
                'bounce_rate'          => round((float)($row['metricValues'][2]['value'] ?? 0) * 100, 1),
                'avg_session_duration' => round((float)($row['metricValues'][3]['value'] ?? 0)),
            ];
        }
        return $rows;
    }

    // Daily sessions trend for sparkline charts
    public function getDailyTrend(int $projectId, string $propertyId, int $days = 30): array
    {
        $token = $this->oauth->getAccessToken($projectId, 'ga4');
        if (!$token) return [];

        $body = $this->runReport($token, $propertyId, [
            'dimensions' => [['name' => 'date']],
            'metrics'    => [['name' => 'sessions']],
            'dateRanges' => [['startDate' => "{$days}daysAgo", 'endDate' => 'today']],
            'orderBys'   => [['dimension' => ['dimensionName' => 'date'], 'desc' => false]],
        ]);

        $trend = [];
        foreach ($body['rows'] ?? [] as $row) {
            $trend[] = [
                'date'     => $row['dimensionValues'][0]['value'] ?? '',
                'sessions' => (int)($row['metricValues'][0]['value'] ?? 0),
            ];
        }
        return $trend;
    }

    private function runReport(string $token, string $propertyId, array $payload): array
    {
        $url  = self::API_BASE . "/properties/{$propertyId}:runReport";
        $ctx  = stream_context_create(['http' => [
            'method'  => 'POST',
            'header'  => "Authorization: Bearer {$token}\r\nContent-Type: application/json\r\n",
            'content' => json_encode($payload),
            'ignore_errors' => true,
        ]]);
        $body = @file_get_contents($url, false, $ctx);
        return $body ? (json_decode($body, true) ?? []) : ['error' => ['message' => 'No response']];
    }
}
