<?php
/**
 * LinkCentral Recent Clicks Class
 *
 * This class handles the functionality for retrieving and displaying
 * the most recent clicks on links.
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

require_once LINKCENTRAL_PLUGIN_DIR . 'includes/admin/insights/referrer-helpers.php';
require_once LINKCENTRAL_PLUGIN_DIR . 'includes/utils/countries.php';

class LinkCentral_Recent_Clicks {

	/**
	 * The main admin object.
	 *
	 * @var LinkCentral_Admin
	 */
	private $admin;

	/**
	 * Constructor.
	 *
	 * @param LinkCentral_Admin $admin The main admin object.
	 */
	public function __construct( $admin ) {
		$this->admin = $admin;
	}

	/**
	 * Retrieve recent clicks for the given filter context.
	 *
	 * @param LinkCentral_Insights_Filters $filters  Filter context.
	 * @param int                          $page     Page number.
	 * @param int                          $per_page Items per page.
	 * @return array
	 */
	public function get_recent_clicks_data( LinkCentral_Insights_Filters $filters, $page = 1, $per_page = 10 ) {
		global $wpdb;

		if ( LinkCentral_Insights_Query_Builder::category_filter_is_empty( $filters ) ) {
			return array(
				'clicks'         => array(),
				'total_pages'    => 1,
				'current_page'   => $page,
				'total_items'    => 0,
				'items_per_page' => $per_page,
			);
		}

		$offset  = ( $page - 1 ) * $per_page;
		$clauses = array();
		$params  = array();

		if ( ! LinkCentral_Insights_Query_Builder::append_stats_filters( $filters, $clauses, $params ) ) {
			return array(
				'clicks'         => array(),
				'total_pages'    => 1,
				'current_page'   => $page,
				'total_items'    => 0,
				'items_per_page' => $per_page,
			);
		}

		$query  = "SELECT SQL_CALC_FOUND_ROWS s.*, s.user_agent, s.referring_url, s.destination_url
			FROM {$wpdb->prefix}linkcentral_stats s
			WHERE " . implode( ' AND ', $clauses ) . '
			ORDER BY s.click_date DESC
			LIMIT %d OFFSET %d';
		$params[] = $per_page;
		$params[] = $offset;

		// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Dynamic WHERE from append_stats_filters(); params bound via prepare().
		$results = $wpdb->get_results( $wpdb->prepare( $query, $params ) );
		// phpcs:enable

		$total_items = (int) $wpdb->get_var( 'SELECT FOUND_ROWS()' );
		$total_pages = max( 1, (int) ceil( $total_items / $per_page ) );

		$link_ids = wp_list_pluck( $results, 'link_id' );
		$posts    = array();

		if ( ! empty( $link_ids ) ) {
			$query = new WP_Query(
				array(
					'post_type'      => 'linkcentral_link',
					'post_status'    => array( 'publish', 'draft', 'private', 'trash' ),
					'posts_per_page' => -1,
					'post__in'       => $link_ids,
					'orderby'        => 'post__in',
				)
			);
			$posts = $query->posts;
		}

		$post_lookup = array();
		foreach ( $posts as $post ) {
			$post_lookup[ $post->ID ] = $post;
		}

		$formatted_results = array_map(
			function ( $result ) use ( $post_lookup ) {
				$click_date = new DateTime( $result->click_date );
				$now        = new DateTime();
				$yesterday  = new DateTime( 'yesterday' );

				if ( $click_date->format( 'Y-m-d' ) === $now->format( 'Y-m-d' ) ) {
					$result->formatted_date = __( 'Today at', 'linkcentral' ) . ' ' . $click_date->format( get_option( 'time_format' ) );
				} elseif ( $click_date->format( 'Y-m-d' ) === $yesterday->format( 'Y-m-d' ) ) {
					$result->formatted_date = __( 'Yesterday at', 'linkcentral' ) . ' ' . $click_date->format( get_option( 'time_format' ) );
				} else {
					$result->formatted_date = $click_date->format( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
				}

				$result->browser           = LinkCentral_User_Agent_Parser::get_browser( $result->user_agent, '-' );
				$device_and_os_info        = LinkCentral_User_Agent_Parser::get_device_and_os( $result->user_agent, '-' );
				$result->device            = $device_and_os_info['type'];
				$result->device_icon       = $device_and_os_info['icon'];
				$result->os                = $device_and_os_info['os'];
				$result->user_agent_info   = array(
					'browser'     => $result->browser,
					'device'      => $result->device,
					'device_icon' => $result->device_icon,
					'os'          => $result->os,
				);

				$result->referrer_drilldown = linkcentral_resolve_referrer_drilldown( $result->referring_url ?? '' );

				if ( ! empty( $result->country ) ) {
					$country_code          = strtoupper( $result->country );
					$result->country       = $country_code;
					$countries_list        = linkcentral_get_countries();
					$result->country_label = ( 'XX' === $country_code )
						? __( 'Unknown', 'linkcentral' )
						: ( $countries_list[ $country_code ] ?? $country_code );
				}

				if ( isset( $post_lookup[ $result->link_id ] ) ) {
					$post                              = $post_lookup[ $result->link_id ];
					$result->post_title                = $post->post_title;
					$result->post_status               = $post->post_status;
					$result->slug                      = $post->post_name;
					$result->is_trashed                = ( 'trash' === $post->post_status );
					$result->is_deleted                = false;
					$result->is_draft                  = ( 'draft' === $post->post_status );
					$result->is_private                = ( 'private' === $post->post_status );
					$result->edit_link                 = get_edit_post_link( $post->ID, 'raw' );
					$result->destination_url_truncated = linkcentral_truncate_url( $result->destination_url );
				} else {
					$result->post_title                = null;
					$result->post_status               = 'deleted';
					$result->slug                      = '';
					$result->is_trashed                = false;
					$result->is_deleted                = true;
					$result->is_draft                  = false;
					$result->is_private                = false;
					$result->edit_link                 = '';
					$result->destination_url_truncated = linkcentral_truncate_url( $result->destination_url );
				}

				return $result;
			},
			$results
		);

		return array(
			'clicks'         => $formatted_results,
			'total_pages'    => $total_pages,
			'current_page'   => $page,
			'total_items'    => $total_items,
			'items_per_page' => $per_page,
		);
	}
}
