<?php

declare(strict_types=1);

namespace Drupal\visitors\Service;

use Drupal\Core\Database\Connection;
use Drupal\visitors\Helper\VisitorsUrl;
use Drupal\visitors\VisitorsUpgradeInterface;
use Drupal\visitors\VisitorsTrackerInterface;

/**
 * A class for upgrading data.
 */
class UpgradeService implements VisitorsUpgradeInterface {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The visitors tracker.
   *
   * @var \Drupal\visitors\VisitorsTrackerInterface
   */
  protected $tracker;

  /**
   * The constructor.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\visitors\VisitorsTrackerInterface $tracker
   *   The visitors tracker.
   */
  public function __construct(Connection $database, VisitorsTrackerInterface $tracker) {
    $this->database = $database;
    $this->tracker = $tracker;
  }

  /**
   * {@inheritdoc}
   */
  public function doLogRecord(array $row): array {
    $log = [];
    $request_time = (int) $row['visitors_date_time'];

    $url = $row['visitors_url'];
    $visitors_url = new VisitorsUrl($url);

    $log['url'] = $visitors_url->getUrl();
    $log['url_prefix'] = $visitors_url->getPrefix();

    $log['uid']               = $row['visitors_uid'] ?? 0;
    $log['title']             = $row['visitors_title'];
    $log['referrer_url']      = $row['visitors_referer'];
    $log['path']              = $row['visitors_path'];
    $log['route']             = $row['route'];
    $log['server']            = $row['server'];
    $log['pf_network']        = $row['pf_network'];
    $log['pf_server']         = $row['pf_server'];
    $log['pf_transfer']       = $row['pf_transfer'];
    $log['pf_dom_processing'] = $row['pf_dom_processing'];
    $log['pf_dom_complete']   = $row['pf_dom_complete'];
    $log['pf_on_load']        = $row['pf_on_load'];
    $log['pf_total']          = $row['pf_total'];
    $log['created']           = $request_time;

    return $log;
  }

  /**
   * {@inheritdoc}
   */
  public function doVisitRecord(array $row): array {
    $visit = [];
    $request_time = (int) $row['visitors_date_time'];

    $visit['location_browser_lang'] = $row['language'];

    $visit['localtime']              = $row['visitor_localtime'];
    $visit['config_browser_engine']  = $row['config_browser_engine'];
    $visit['config_browser_name']    = $row['config_browser_name'];
    $visit['config_browser_version'] = $row['config_browser_version'];
    $visit['config_client_type']     = $row['config_client_type'];
    $visit['config_device_brand']    = $row['config_device_brand'];
    $visit['config_device_model']    = $row['config_device_model'];
    $visit['config_device_type']     = $row['config_device_type'];
    $visit['config_os']              = $row['config_os'];
    $visit['config_os_version']      = $row['config_os_version'];
    $visit['bot']                    = $row['bot'];
    $visit['config_resolution']      = $row['config_resolution'];
    $visit['config_pdf']             = $row['config_pdf'];
    $visit['config_flash']           = $row['config_flash'];
    $visit['config_java']            = $row['config_java'];
    $visit['config_quicktime']       = $row['config_quicktime'];
    $visit['config_realplayer']      = $row['config_realplayer'];
    $visit['config_windowsmedia']    = $row['config_windowsmedia'];
    $visit['config_silverlight']     = $row['config_silverlight'];
    $visit['config_cookie']          = $row['config_cookie'];
    $visit['location_continent']     = $row['location_continent'];
    $visit['location_country']       = $row['location_country'];
    $visit['location_region']        = $row['location_region'] ?? NULL;
    $visit['location_city']          = $row['location_city'] ?? NULL;
    $visit['location_latitude']      = $row['location_latitude'] ?? NULL;
    $visit['location_longitude']     = $row['location_longitude'] ?? NULL;
    $visit['visitor_id']             = $row['visitor_id'];
    $visit['total_time']             = 0;
    $visit['page_count']             = 0;
    $visit['returning']              = 0;
    $visit['visit_count']            = 0;
    $visit['entry_time']             = $request_time;
    $visit['exit_time']              = $request_time;
    $visit['location_ip']            = $row['visitors_ip'];

    return $visit;
  }

  /**
   * {@inheritdoc}
   */
  public function getVisitorsRows(int $batch = 50): array {
    $select = $this->database->select('visitors', 'v');
    $rows = $select->fields('v')
      ->orderBy('v.visitors_date_time', 'ASC')
      ->range(0, $batch)
      ->execute()->fetchAll();

    return $rows;
  }

  /**
   * {@inheritdoc}
   */
  public function deleteVisitorsRow($id) {
    $this->database
      ->delete('visitors')
      ->condition('visitors_id', $id)
      ->execute();
  }

  /**
   * {@inheritdoc}
   */
  public function getTotal(): int {
    $select = $this->database->select('visitors', 'v');
    $select->fields('v')
      ->countQuery();

    $count = $select->execute()->fetchField();

    return (int) $count;
  }

  /**
   * {@inheritdoc}
   */
  public function upgradeRow(array $row) {
    $id = $row['visitors_id'];
    $request_time = (int) $row['visitors_date_time'];

    $visit = $this->doVisitRecord($row);
    $log = $this->doLogRecord($row);
    $uid = (int) $log['uid'];
    $visit['uid'] = $uid == 0 ? NULL : $uid;

    $visit_id = $this->tracker->getVisitId($visit, $request_time);
    $log['visit_id'] = $visit_id;
    $log_id = $this->tracker->writeLog($log);

    $this->tracker->updateVisit($visit_id, $log_id, $request_time, $uid);

    $this->deleteVisitorsRow($id);
  }

}
