<?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\CustomDimensions;

use Piwik\API\Request;
use Piwik\Plugins\CustomDimensions\Dao\LogTable;
use Piwik\Plugins\CustomDimensions\Tracker\CustomDimensionsRequestProcessor;
use Piwik\Plugins\Live\VisitorDetailsAbstract;
use Piwik\View;
class VisitorDetails extends VisitorDetailsAbstract
{
    public function extendVisitorDetails(&$visitor)
    {
        if (empty($visitor['idSite'])) {
            return;
        }
        $idSite = $visitor['idSite'];
        $dimensions = $this->getActiveCustomDimensionsInScope($idSite, \Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_VISIT);
        foreach ($dimensions as $dimension) {
            // field in DB, eg custom_dimension_1
            $field = LogTable::buildCustomDimensionColumnName($dimension);
            // field for user, eg dimension1
            $column = CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($dimension);
            if (array_key_exists($field, $this->details)) {
                $visitor[$column] = $this->details[$field];
            } else {
                $visitor[$column] = null;
            }
        }
    }
    public function extendActionDetails(&$action, $nextAction, $visitorDetails)
    {
        if (empty($visitorDetails['idSite'])) {
            return;
        }
        $idSite = $visitorDetails['idSite'];
        $dimensions = $this->getActiveCustomDimensionsInScope($idSite, \Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_ACTION);
        foreach ($dimensions as $dimension) {
            // field in DB, eg custom_dimension_1
            $field = LogTable::buildCustomDimensionColumnName($dimension);
            // field for user, eg dimension1
            $column = CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($dimension);
            if (array_key_exists($field, $action)) {
                $action[$column] = $action[$field];
            } else {
                $action[$column] = null;
            }
            unset($action[$field]);
        }
        static $indices;
        if (is_null($indices)) {
            $logTable = new \Piwik\Plugins\CustomDimensions\Dao\LogTable(\Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_ACTION);
            $indices = $logTable->getInstalledIndexes();
        }
        foreach ($indices as $index) {
            $field = \Piwik\Plugins\CustomDimensions\Dao\LogTable::buildCustomDimensionColumnName($index);
            unset($action[$field]);
        }
    }
    public function renderVisitorDetails($visitorDetails)
    {
        if (empty($visitorDetails['idSite'])) {
            return [];
        }
        $view = new View('@CustomDimensions/_visitorDetails');
        $view->sendHeadersWhenRendering = \false;
        $view->visitInfo = $visitorDetails;
        $view->customDimensions = $this->getCustomDimensionsFromVisit($visitorDetails);
        return [[40, $view->render()]];
    }
    protected function getCustomDimensionsFromVisit($visitorDetails)
    {
        $idSite = $visitorDetails['idSite'];
        $dimensions = $this->getActiveCustomDimensionsInScope($idSite, \Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_VISIT);
        $customDimensions = array();
        if (count($dimensions) > 0) {
            foreach ($dimensions as $dimension) {
                $column = CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($dimension);
                $customDimensions[] = array('id' => $dimension['idcustomdimension'], 'name' => $dimension['name'], 'value' => $visitorDetails[$column]);
            }
        }
        return $customDimensions;
    }
    public function renderActionTooltip($action, $visitInfo)
    {
        $customDimensions = $this->getCustomDimensionsFromAction($action, $visitInfo);
        if (empty($customDimensions)) {
            return [];
        }
        $action['customDimensions'] = $customDimensions;
        $view = new View('@CustomDimensions/_actionTooltip');
        $view->sendHeadersWhenRendering = \false;
        $view->action = $action;
        return [[30, $view->render()]];
    }
    protected function getCustomDimensionsFromAction($action, $visitInfo)
    {
        $idSite = $visitInfo['idSite'];
        $dimensions = $this->getActiveCustomDimensionsInScope($idSite, \Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_ACTION);
        $customDimensions = array();
        foreach ($dimensions as $dimension) {
            $column = CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($dimension);
            $customDimensions[$dimension['name']] = $action[$column];
        }
        return $customDimensions;
    }
    protected $activeCustomDimensionsCache = array();
    protected function getActiveCustomDimensionsInScope($idSite, $scope)
    {
        if (array_key_exists($idSite . $scope, $this->activeCustomDimensionsCache)) {
            return $this->activeCustomDimensionsCache[$idSite . $scope];
        }
        $dimensions = Request::processRequest('CustomDimensions.getConfiguredCustomDimensionsHavingScope', ['idSite' => $idSite, 'scope' => $scope], $default = []);
        $dimensions = array_filter($dimensions, function ($dimension) use($scope) {
            return $dimension['active'] && $dimension['scope'] === $scope;
        });
        $this->activeCustomDimensionsCache[$idSite . $scope] = $dimensions;
        return $this->activeCustomDimensionsCache[$idSite . $scope];
    }
    protected $customDimensions = [];
    protected $lastVisit = null;
    public function initProfile($visits, &$profile)
    {
        $this->customDimensions = [\Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_ACTION => [], \Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_VISIT => []];
        $this->lastVisit = $visits->getLastRow();
    }
    public function handleProfileAction($action, &$profile)
    {
        $customDimensions = $this->getCustomDimensionsFromAction($action, $this->lastVisit);
        if (!empty($customDimensions)) {
            foreach ($customDimensions as $name => $value) {
                $scope = \Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_ACTION;
                if (empty($value)) {
                    continue;
                }
                if (!array_key_exists($name, $this->customDimensions[$scope])) {
                    $this->customDimensions[$scope][$name] = [];
                }
                if (!array_key_exists($value, $this->customDimensions[$scope][$name])) {
                    $this->customDimensions[$scope][$name][$value] = 0;
                }
                $this->customDimensions[$scope][$name][$value]++;
            }
        }
    }
    public function handleProfileVisit($visit, &$profile)
    {
        $customDimensions = $this->getCustomDimensionsFromVisit($visit);
        if (!empty($customDimensions)) {
            foreach ($customDimensions as $dimension) {
                $scope = \Piwik\Plugins\CustomDimensions\CustomDimensions::SCOPE_VISIT;
                $name = $dimension['name'];
                $value = $dimension['value'];
                if (empty($value)) {
                    continue;
                }
                if (!array_key_exists($name, $this->customDimensions[$scope])) {
                    $this->customDimensions[$scope][$name] = [];
                }
                if (!array_key_exists($value, $this->customDimensions[$scope][$name])) {
                    $this->customDimensions[$scope][$name][$value] = 0;
                }
                $this->customDimensions[$scope][$name][$value]++;
            }
        }
    }
    public function finalizeProfile($visits, &$profile)
    {
        $customDimensions = $this->customDimensions;
        foreach ($customDimensions as $scope => &$dimensions) {
            if (empty($dimensions)) {
                unset($customDimensions[$scope]);
                continue;
            }
            foreach ($dimensions as $name => &$values) {
                arsort($values);
            }
        }
        if (!empty($customDimensions)) {
            $profile['customDimensions'] = $this->convertForProfile($customDimensions);
        }
    }
    protected function convertForProfile($customDimensions)
    {
        $convertedDimensions = [];
        foreach ($customDimensions as $scope => $scopeDimensions) {
            $convertedDimensions[$scope] = [];
            foreach ($scopeDimensions as $name => $values) {
                $dimension = ['name' => $name, 'values' => []];
                foreach ($values as $value => $count) {
                    $dimension['values'][] = ['value' => $value, 'count' => $count];
                }
                $convertedDimensions[$scope][] = $dimension;
            }
        }
        return $convertedDimensions;
    }
}
