<?php

/**
 * Matomo - free/libre analytics platform
 *
 * @link    https://matomo.org
 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 */
namespace Piwik\Plugins\PagePerformance;

use Piwik\API\Request;
use Piwik\Common;
use Piwik\DataTable;
use Piwik\Exception\InvalidRequestParameterException;
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
use Piwik\Plugin\Controller as PluginController;
use Piwik\Plugin\ReportsProvider;
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution as EvolutionViz;
use Piwik\Plugins\PagePerformance\Visualizations\JqplotGraph\StackedBarEvolution;
use Piwik\View;
use Piwik\ViewDataTable\Factory as ViewDataTableFactory;
class Controller extends PluginController
{
    public function indexPagePerformance()
    {
        $this->checkSitePermission();
        $view = new View('@PagePerformance/getPagePerformancePopover');
        $dataTable = $this->getEvolutionTable();
        $view->graph = $this->getRowEvolutionGraph($dataTable);
        $view->metrics = '';
        $metrics = \Piwik\Plugins\PagePerformance\Metrics::getPagePerformanceMetrics();
        foreach ($metrics as $metric) {
            $view->metrics .= sprintf('<strong>%s</strong>: %s<br />', $metric->getTranslatedName(), $metric->getDocumentation());
        }
        return $view->render();
    }
    private function validateApiMethod(string $method) : void
    {
        $validApis = array_map(function ($method) {
            return 'Actions.' . $method;
        }, \Piwik\Plugins\PagePerformance\PagePerformance::$availableForMethods);
        if (!in_array($method, $validApis, \true)) {
            throw new InvalidRequestParameterException('Invalid apiMethod provided.');
        }
    }
    protected function getEvolutionTable()
    {
        // Note: Using unsanitized request parameters here, as they will be passed through to an API method,
        // which should handle sanitizing if needed
        $request = \Piwik\Request::fromRequest();
        $apiMethod = $request->getStringParameter('apiMethod');
        $period = $request->getStringParameter('period');
        $date = $request->getStringParameter('date');
        $this->validateApiMethod($apiMethod);
        $params = ['method' => $apiMethod, 'period' => 'range' === $period ? 'day' : $period, 'label' => $request->getStringParameter('label', ''), 'idSite' => $this->idSite, 'segment' => $request->getStringParameter('segment', ''), 'date' => 'range' === $period ? $date : EvolutionViz::getDateRangeAndLastN($period, $date)[0], 'format' => 'original', 'flat' => $request->getIntegerParameter('flat', 0), 'serialize' => '0'];
        /** @var DataTable $dataTable */
        $dataTable = Request::processRequest($apiMethod, $params, []);
        $dataTable->deleteColumn('label');
        return $dataTable;
    }
    /**
     * @return string|void
     * @throws \Exception
     */
    public function getRowEvolutionGraph($dataTable = null)
    {
        $this->checkSitePermission();
        $apiMethod = \Piwik\Request::fromRequest()->getStringParameter('apiMethod');
        $this->validateApiMethod($apiMethod);
        if (empty($dataTable)) {
            $dataTable = $this->getEvolutionTable();
        }
        // set up the view data table
        $view = ViewDataTableFactory::build(StackedBarEvolution::ID, $apiMethod, 'PagePerformance.getRowEvolutionGraph', $forceDefault = \true);
        $view->setDataTable($dataTable);
        $view->config->columns_to_display = array_keys(\Piwik\Plugins\PagePerformance\Metrics::getPagePerformanceMetrics());
        $view->requestConfig->request_parameters_to_modify['label'] = '';
        $view->config->show_goals = \false;
        $view->config->show_search = \false;
        $view->config->show_all_views_icons = \false;
        $view->config->show_related_reports = \false;
        $view->config->show_series_picker = \false;
        $view->config->show_footer_message = \false;
        $view->config->selectable_columns = array_keys(\Piwik\Plugins\PagePerformance\Metrics::getPagePerformanceMetrics());
        return $this->renderView($view);
    }
    public function getEvolutionGraph()
    {
        $this->checkSitePermission();
        $columns = Common::getRequestVar('columns', \false);
        if (\false !== $columns) {
            $columns = Piwik::getArrayFromApiParameter($columns);
        }
        $view = ViewDataTableFactory::build(StackedBarEvolution::ID, 'PagePerformance.get', $this->pluginName . '.' . __FUNCTION__, $forceDefault = \true);
        $view->config->show_goals = \false;
        $performanceMetrics = array_keys(\Piwik\Plugins\PagePerformance\Metrics::getPagePerformanceMetrics());
        if (!empty($columns)) {
            $view->config->columns_to_display = array_intersect($columns, $performanceMetrics);
        }
        if (empty($view->config->columns_to_display)) {
            $view->config->columns_to_display = $performanceMetrics;
        }
        $view->config->documentation = Piwik::translate('PagePerformance_EvolutionOverPeriod') . '<br /><br />';
        $metrics = \Piwik\Plugins\PagePerformance\Metrics::getPagePerformanceMetrics();
        foreach ($metrics as $metric) {
            $view->config->documentation .= sprintf('<strong>%s</strong>: %s<br />', $metric->getTranslatedName(), $metric->getDocumentation());
        }
        $report = ReportsProvider::factory('PagePerformance', 'get');
        $view->config->selectable_columns = array_keys(\Piwik\Plugins\PagePerformance\Metrics::getPagePerformanceMetrics());
        $numberFormatter = new Formatter\Html();
        $metrics = $report->getMetrics();
        $view->config->filters[] = function (DataTable $table) use($numberFormatter, $metrics) {
            $firstRow = $table->getFirstRow();
            if ($firstRow) {
                foreach ($metrics as $metric => $name) {
                    $metricValue = $firstRow->getColumn($metric);
                    if (\false !== $metricValue) {
                        $firstRow->setColumn($metric, $numberFormatter->getPrettyTimeFromSeconds($metricValue));
                    }
                }
            }
        };
        $view->config->addTranslations(\Piwik\Plugins\PagePerformance\Metrics::getMetricTranslations());
        return $this->renderView($view);
    }
}
