<?php
require_once dirname(__FILE__) . "/../../../../base/database.php";

class Counter
{
  /*
  * Private members
  */

  private PDO $db;
  private string $siteID;

  /*
  * Constructor
  */

  public function __construct(string $siteID = null)
  {
    $this->db = DB::openConnection();

    if (empty($siteID)) {
      $this->siteID = substr($_SERVER["REQUEST_URI"], strlen($_SERVER["REQUEST_URI"]) - 256);
    } else {
      $this->siteID = $siteID;
    }
  }

  /*
  * Render Component
  */

  public function render()
  {
    $this->cleanupIPs();
    $hasVisited = $this->hasVisited();
    if (!$hasVisited) {
      $this->addHit();
      $this->addIp();
    }

    $ret =
      <<<EOT
    <style>
      .span-v3Yq3 {
        display: inline-block;
        padding: 6px 6px 4px;
        border-radius: 3px;
        background: #cccccc;
        margin-right: -2px;
      }

      .center-v3Yq3 {
        display: flex;
        justify-content: center;
        gap: 5px;
        width: 50%;
        margin: 20px auto;
      }

      .message-v3Yq3 {
        color: #aaaaaa;
        font-size: 12px;
        text-align: center;
      }
    </style>
    <div>
      <div class="center-v3Yq3">
    EOT;
    foreach (mb_str_split(($this->getHits()) . "") as $digit) {
      $ret .=
        <<<EOT
      <span class="span-v3Yq3">$digit</span>
      EOT;
    }
    $ret .=
      <<<EOT
      </div>
      <div class="center-v3Yq3 message-v3Yq3">
        Have visited this site.
      EOT;
    if (!$hasVisited) {
      $ret .=
        <<<EOT
        <br />
        This is your first visit tody
        EOT;
    }
    $ret .=
      <<<EOT
      </div>
    </div>
    EOT;

    echo $ret;
  }

  /*
  * Implementation
  */

  private function getHits()
  {
    $query = "
      SELECT
        hits
      FROM
        Counter
      WHERE
        siteID LIKE :SID";

    $stmt = $this->db->prepare($query);
    $stmt->bindValue(":SID", $this->siteID);
    $stmt->execute();
    $hits = $stmt->fetch(PDO::FETCH_COLUMN);
    return $hits !== false ? $hits : 0;
  }

  private function addHit()
  {
    $query = "
      INSERT INTO
        Counter(siteID, hits)
      VALUES
        (:SID, 1)
      ON DUPLICATE KEY UPDATE
        hits = hits + 1";

    $stmt = $this->db->prepare($query);
    $stmt->bindValue(":SID", $this->siteID);
    $stmt->execute();
  }

  private function addIP()
  {
    $query = "
      INSERT INTO
        CounterIP(siteID, ip, timestamp)
      VALUES
        (:SID, :IP, NOW())";

    $stmt = $this->db->prepare($query);
    $stmt->bindValue(":SID", $this->siteID);
    $stmt->bindValue(":IP", $_SERVER['REMOTE_ADDR']);
    $stmt->execute();
  }

  private function cleanupIPs()
  {
    $query = "
      DELETE FROM
        CounterIP
      WHERE
        TIMESTAMPDIFF(DAY, timestamp, NOW()) > 1";

    $stmt = $this->db->prepare($query);
    $stmt->execute();
  }

  private function hasVisited()
  {
    $query = "
      SELECT
        COUNT(*)
      FROM
        CounterIP
      WHERE
          siteID = :SID
        AND
          ip = :IP
        AND
          TIMESTAMPDIFF(DAY, timestamp, NOW()) <= 1";

    $stmt = $this->db->prepare($query);
    $stmt->bindValue(":SID", $this->siteID);
    $stmt->bindValue(":IP", $_SERVER['REMOTE_ADDR']);
    $stmt->execute();
    $cnt = $stmt->fetch(PDO::FETCH_COLUMN);
    return $cnt > 0;
  }
}
