<?php

namespace Blazemedia\Blackhole\Tools;

use Google\Analytics\Data\V1beta\Filter;
use Google\Analytics\Data\V1beta\Metric;
use Google\Analytics\Data\V1beta\DateRange;
use Google\Analytics\Data\V1beta\Dimension;
use Google\Analytics\Data\V1beta\MetricType;
use Google\Analytics\Data\V1beta\RunReportResponse;
use Google\Analytics\Data\V1beta\BetaAnalyticsDataClient;
use Google\Analytics\Data\V1beta\FilterExpression;
use Google\Analytics\Data\V1beta\Filter\StringFilter;
use Google\Analytics\Data\V1beta\Filter\StringFilter\MatchType;

class GA4Client {

    private $client;

    /// Service account credentials in JSON format
    /// poi lo mettiamo da env
    const KEY_FILE_LOCATION = __DIR__ . '/../google_credentials/ga_fetcher_composed-slice-349709-ed3cff527c69.json';

    function __construct( private $property_id ) {

        $this->client = $this->getClient();

    }

    /**
     * ATTUALMENTE NON VIENE USATA 
     * Ritorna gli articoli più visti in un elenco di
     * oggetti { slug, users }
     *
     * @param integer $number - numero di articoli da visualizzare
     * @param string $start_date - data di inizio
     * @param string $end_date - data di fine
     * @param integer $threshold - soglia minima di utenti
     *
     * @return array
     */
    function getMostViewedPages( $number = 10, $start_date = '1weekAgo', $end_date = 'today', $threshold = 2000 ) {

        // Make an API call.
        // https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema?hl=en#dimensions

        $response = $this->client->runReport([

            'property' => 'properties/' . $this->property_id,

            'dateRanges' => [ new DateRange([ 'start_date' => $start_date, 'end_date' => $end_date ]) ],
            'dimensions' => [ new Dimension([ 'name' => 'landingPage' ]) ],
            'metrics'    => [ new Metric([ 'name' => 'totalUsers' ]) ],
            'limit'      => $number

        ]);

        $mostViewed = [];

        /// getRows() è una sorta di iterator
        foreach( $response->getRows() as $row ) {

            /// la posizione [ 0 ] in dimesions è landingPage
            $path = $row->getDimensionValues() [ 0 ]->getValue();

            /// prende le parti del pathname dell'articolo ( esclude quelle vuote )
            $path_parts = array_filter( explode( '/', $path ), fn( $part )  => !empty($part) );

            /// prende lo slug
            $slug = array_pop( $path_parts );

            /// totalUsers è la metrica [ 0 ]
            $totalUsers = $row->getMetricValues()[ 0 ]->getValue();

            /// se trova utenti  sopra la soglia desiderata
            if( $totalUsers > $threshold ) {

                /// ... aggiunge l'articolo con il numero di utenti
                $mostViewed[] = ( object ) [

                    'slug'  => $slug,
                    'users' => $totalUsers,
                ];
            }
        }

        return $mostViewed;
    }


    /**
     * Ritorna il numero di utenti che hanno visalizzato
     * una certa pagina
     *
     * @param [type] $slug
     * @param string $start_date
     * @param string $end_date
     * @return object
     */
    function getUsers( $slug, $start_date = '1weekAgo', $end_date = 'today' ) {

        // Make an API call.
        // https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema?hl=en#dimensions

        $response = $this->client->runReport([

            'property' => 'properties/' . $this->property_id,

            'dateRanges' => [ new DateRange([ 'start_date' => $start_date, 'end_date' => $end_date ]) ],
            'dimensions' => [ new Dimension([ 'name' => 'landingPage' ]) ],
            'metrics'    => [ new Metric([ 'name' => 'totalUsers' ]) ],
            'limit' => 1,
            'dimensionFilter' => new FilterExpression([

                'filter' => new Filter([
                    'field_name' => 'landingPage',
                    'string_filter'=> new StringFilter( [
                        'value' => $slug,
                        'match_type' => MatchType::CONTAINS,
                        'case_sensitive' => false
                    ])
                ])
            ]),
        ]);

        $rows = $response->getRows();


        if( !isset( $rows[ 0 ] ) ) return (object) [

            'slug'  => $slug,
            'users' => 0
        ];

        $row = $rows[ 0 ];

        /// la posizione [ 0 ] è landingPage
        $path = $row->getDimensionValues() [ 0 ]->getValue();

        /// totalUsers è la metrica [ 0 ]
        $totalUsers = $row->getMetricValues()[ 0 ]->getValue();

        return (object) [

            'slug'  => $path,
            'users' => $totalUsers
        ];

    }

    /**
     * Istanzia un client per GA4
     *
     * @return BetaAnalyticsDataClient client
     */
    protected function getClient() {

        $credentialsJsonPath = GA4Client::KEY_FILE_LOCATION;

        $credentials = file_get_contents( $credentialsJsonPath );

        if( empty( $credentials ) ) throw new \ErrorException( 'Credentials file not found' );

        return new BetaAnalyticsDataClient([
            'credentials' => json_decode( $credentials, true )
        ]);
    }



    // Print results of a runReport call.
    function printRunReportResponse(RunReportResponse $response)
    {
        // [START analyticsdata_print_run_report_response_header]
        printf('%s rows received%s', $response->getRowCount(), PHP_EOL);

        foreach ($response->getDimensionHeaders() as $dimensionHeader) {

            printf('Dimension header name: %s%s', $dimensionHeader->getName(), PHP_EOL);
        }

        foreach ($response->getMetricHeaders() as $metricHeader) {
            printf(
                'Metric header name: %s (%s)%s',
                $metricHeader->getName(),
                MetricType::name( $metricHeader->getType() ),
                PHP_EOL
            );
        }
        // [END analyticsdata_print_run_report_response_header]

        // [START analyticsdata_print_run_report_response_rows]
        print 'Report result: ' . PHP_EOL;

        $mostViewed = [];

        foreach( $response->getRows() as $row ) {

            if( count( $mostViewed ) == 10 ) break;

            /// la posizione [ 0 ] è landingPage
            $path = $row->getDimensionValues() [ 0 ]->getValue();

            $path_parts = array_filter( explode( '/', $path ), fn( $part )  => !empty($part) );

            $slug = array_pop( $path_parts );

            /// totalUsers è la metrica [ 0 ]
            $totalUsers = $row->getMetricValues()[ 0 ]->getValue();



                $mostViewed[] = ( object ) [

                    'slug'  => $slug,
                    'users' => $totalUsers,
                ];


            /*

            $dimensionValues = [];
            foreach( $row->getDimensionValues() as $dim ) $dimensionValues[] = $dim->getValue();

            $metricValues = [];
            foreach( $row->getMetricValues() as $metric ) $metricValues[] = $metric->getValue();

            var_dump( $dimensionValues, $metricValues ); die;

            //$dimensionValues = array_map( fn( $dim ) => $dim->getValues() , $row->getDimensionValues() ) ;

            $dimension = $row->getDimensionValues()[0]->getValue();
            $metric    = $row->getMetricValues()[0]->getValue();

            */
        }


        var_dump( $mostViewed  ); die;


    }


}
