<?php

class pluginVisitsStats extends Plugin
{

	public function init()
	{
		global $L;
		$this->dbFields = array(
			'label'         => $L->g('Visits'),
			'excludeAdmins' => false
		);
	}

	public function adminHead()
	{
		if ($GLOBALS['ADMIN_VIEW'] !== 'dashboard') {
			return false;
		}

		$html  = $this->includeCSS('chart.min.css');
		$html .= $this->includeJS('chart.bundle.min.js');
		return $html;
	}

	// Plugin form for settings
	public function form()
	{
		global $L;

		$html  = '<div class="mb-3">';
		$html .= '<label class="form-label" for="label">' . $L->get('Label') . '</label>';
		$html .= '<input class="form-control" id="label" name="label" type="text" dir="auto" value="' . $this->getValue('label') . '">';
		$html .= '<div class="form-text">' . $L->get('This title is almost always used in the sidebar of the site') . '</div>';
		$html .= '</div>';

		if (defined('BLUDIT_PRO')) {
			$html .= '<div class="mb-3">';
			$html .= '<label class="form-label" for="excludeAdmins">' . $L->get('Exclude administrators users') . '</label>';
			$html .= '<select class="form-select" id="excludeAdmins" name="excludeAdmins">';
			$html .= '<option value="true" ' . ($this->getValue('excludeAdmins') === true ? 'selected' : '') . '>' . $L->get('Enabled') . '</option>';
			$html .= '<option value="false" ' . ($this->getValue('excludeAdmins') === false ? 'selected' : '') . '>' . $L->get('Disabled') . '</option>';
			$html .= '</select>';
			$html .= '</div>';
		}

		return $html;
	}

	public function siteBodyEnd()
	{
		$currentDate = Date::current('Y-m-d');
		$isNewDay = !file_exists($this->workspace() . $currentDate . '.log');
		$visitorAdded = $this->addVisitor();
		if ($isNewDay && $visitorAdded) {
			$this->deleteOldLogs();
		}
	}

	// Delete log files older than 7 days
	public function deleteOldLogs()
	{
		$logs = Filesystem::listFiles($this->workspace(), '*', 'log', false);
		rsort($logs);
		$remove = array_slice($logs, 7);
		foreach ($remove as $log) {
			Filesystem::rmfile($log);
		}
	}

	// Returns the number of visits for a given date (YYYY-MM-DD)
	public function visits($date)
	{
		$file = $this->workspace() . $date . '.log';
		if (!file_exists($file)) {
			return 0;
		}
		$handle = @fopen($file, 'rb');
		if ($handle === false) {
			return 0;
		}

		// The amount of visits is the number of lines on the file
		$lines = 0;
		while (!feof($handle)) {
			$lines += substr_count(fread($handle, 8192), PHP_EOL);
		}
		@fclose($handle);
		return $lines;
	}

	// Returns the number of unique visitors for a given date (YYYY-MM-DD)
	public function uniqueVisitors($date)
	{
		$file = $this->workspace() . $date . '.log';
		if (!file_exists($file)) {
			return 0;
		}
		$lines = @file($file);
		if (empty($lines)) {
			return 0;
		}

		$seen = array();
		foreach ($lines as $line) {
			$data = json_decode($line, true);
			if (is_array($data) && isset($data[0]) && is_string($data[0]) && $data[0] !== '') {
				$seen[$data[0]] = true;
			}
		}
		return count($seen);
	}

	// Single-pass read of a day log returning [total, unique]
	private function readCounts($date)
	{
		$file = $this->workspace() . $date . '.log';
		if (!file_exists($file)) {
			return array(0, 0);
		}
		$handle = @fopen($file, 'rb');
		if ($handle === false) {
			return array(0, 0);
		}
		$total = 0;
		$seen  = array();
		while (($line = fgets($handle)) !== false) {
			$total++;
			$data = json_decode($line, true);
			if (is_array($data) && isset($data[0]) && is_string($data[0]) && $data[0] !== '') {
				$seen[$data[0]] = true;
			}
		}
		@fclose($handle);
		return array($total, count($seen));
	}

	// Returns visits and unique-visitor counts for the last $days days
	// Returns ['labels'=>[], 'visits'=>[], 'unique'=>[], 'total'=>int]
	public function getLastDaysData($days = 7)
	{
		$result = array('labels' => array(), 'visits' => array(), 'unique' => array(), 'total' => 0);
		for ($i = $days - 1; $i >= 0; $i--) {
			$date = Date::currentOffset('Y-m-d', '-' . $i . ' day');
			list($v, $u) = $this->readCounts($date);
			$result['labels'][] = Date::format($date, 'Y-m-d', 'D');
			$result['visits'][] = $v;
			$result['unique'][] = $u;
			$result['total']   += $v;
		}
		return $result;
	}

	// Add a line to the current day log file
	public function addVisitor()
	{
		global $security;
		if (Cookie::get('BLUDIT-KEY') && defined('BLUDIT_PRO') && $this->getValue('excludeAdmins')) {
			return false;
		}
		$currentTime = Date::current('Y-m-d H:i:s');
		$ip     = $security->getUserIp();
		$hashIP = md5($ip);

		$line        = json_encode(array($hashIP, $currentTime));
		$currentDate = Date::current('Y-m-d');
		$logFile     = $this->workspace() . $currentDate . '.log';

		return file_put_contents($logFile, $line . PHP_EOL, FILE_APPEND | LOCK_EX) !== false;
	}
}
