<?php

/**
 * LinkCentral Total Clicks Class
 *
 * This class handles the functionality for retrieving and displaying
 * total click statistics for all links and specific links in the plugin.
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
// Exit if accessed directly
class LinkCentral_Total_Clicks {
    /**
     * The main admin object.
     */
    private $admin;

    /**
     * Constructor.
     */
    public function __construct( $admin ) {
        $this->admin = $admin;
    }

    /**
     * Initialize the class and set up WordPress hooks.
     */
    public function init() {
        // Register AJAX actions for getting stats and specific link stats
        add_action( 'wp_ajax_linkcentral_get_stats', array($this, 'ajax_get_stats') );
        add_action( 'wp_ajax_linkcentral_get_link_stats', array($this, 'ajax_get_link_stats') );
        add_action( 'wp_ajax_linkcentral_get_category_stats', array($this, 'ajax_get_category_stats') );
    }

    /**
     * Get the date range for statistics based on input parameters.
     *
     * @param int|string $days       The number of days to retrieve data for
     * @param string     $start_date Custom range start date
     * @param string     $end_date   Custom range end date
     * @param bool       $since_start Whether to get data since first click
     * @param int       $link_id     Optional link ID for specific link stats
     * @return array Array containing start and end DateTime objects
     */
    private function get_date_range(
        $days,
        $start_date,
        $end_date,
        $since_start = false,
        $link_id = null
    ) {
        global $wpdb;
        if ( $since_start ) {
        }
        if ( $start_date && $end_date ) {
            $start = new DateTime($start_date);
            $end = new DateTime($end_date);
            $end->modify( '+1 day' );
            return array($start, $end);
        }
        // Default to last N days
        $end = new DateTime('tomorrow');
        $start = clone $end;
        $start->modify( sprintf( "-%d days", ( $days ?: 7 ) ) );
        return array($start, $end);
    }

    /**
     * Get click statistics data.
     *
     * @param array $date_range Array of start and end DateTime objects
     * @param int   $link_id    Optional link ID for specific link stats
     * @param int   $category_id Optional category ID for category-specific stats
     * @return array Statistics data
     */
    private function get_click_data( $date_range, $link_id = null, $category_id = null ) {
        global $wpdb;
        list( $start, $end ) = $date_range;
        $track_unique_visitors = get_option( 'linkcentral_track_unique_visitors', false );
        $query = "SELECT DATE(click_date) as date, COUNT(*) as clicks";
        if ( $track_unique_visitors ) {
            $query .= ", SUM(first_click) as unique_clicks";
        }
        $query .= " FROM {$wpdb->prefix}linkcentral_stats s";
        $where_clauses = array("s.click_date >= %s", "s.click_date < %s");
        $query_params = array($start->format( 'Y-m-d' ), $end->format( 'Y-m-d' ));
        if ( $link_id ) {
            $where_clauses[] = "s.link_id = %d";
            $query_params[] = $link_id;
        }
        if ( $category_id ) {
            // Join with posts and term relationships to filter by category
            $query .= " INNER JOIN {$wpdb->posts} p ON s.link_id = p.ID";
            $query .= " INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id";
            $query .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";
            $where_clauses[] = "tt.taxonomy = 'linkcentral_category'";
            $where_clauses[] = "tt.term_id = %d";
            $query_params[] = $category_id;
        }
        $query .= " WHERE " . implode( " AND ", $where_clauses );
        $query .= " GROUP BY DATE(s.click_date)";
        // Execute the query - use prepare only if there are placeholders
        if ( !empty( $query_params ) ) {
            $results = $wpdb->get_results( $wpdb->prepare( $query, $query_params ) );
        } else {
            $results = $wpdb->get_results( $query );
        }
        // Initialize data structure
        $data = array(
            'labels'        => array(),
            'clicks'        => array(),
            'unique_clicks' => array(),
        );
        // Create lookup arrays for actual click data
        $click_data = array();
        $unique_click_data = array();
        foreach ( $results as $row ) {
            $click_data[$row->date] = (int) $row->clicks;
            if ( $track_unique_visitors ) {
                $unique_click_data[$row->date] = (int) $row->unique_clicks;
            }
        }
        // Fill in the data for each day in the range
        $interval = new DateInterval('P1D');
        $date_range = new DatePeriod($start, $interval, $end);
        foreach ( $date_range as $date ) {
            $date_string = $date->format( 'Y-m-d' );
            $data['labels'][] = $date->format( 'c' );
            $data['clicks'][] = ( isset( $click_data[$date_string] ) ? $click_data[$date_string] : 0 );
            $data['unique_clicks'][] = ( isset( $unique_click_data[$date_string] ) ? $unique_click_data[$date_string] : 0 );
        }
        return $data;
    }

    /**
     * AJAX handler for retrieving statistics for all links.
     */
    public function ajax_get_stats() {
        check_ajax_referer( 'linkcentral_admin_nonce', 'nonce' );
        $days = ( isset( $_POST['days'] ) ? sanitize_text_field( wp_unslash( $_POST['days'] ) ) : 30 );
        $start_date = ( isset( $_POST['start_date'] ) ? sanitize_text_field( wp_unslash( $_POST['start_date'] ) ) : null );
        $end_date = ( isset( $_POST['end_date'] ) ? sanitize_text_field( wp_unslash( $_POST['end_date'] ) ) : null );
        $since_start = ( isset( $_POST['since_start'] ) ? filter_var( $_POST['since_start'], FILTER_VALIDATE_BOOLEAN ) : false );
        if ( $start_date ) {
            $start_date = gmdate( 'Y-m-d', strtotime( $start_date ) );
        }
        if ( $end_date ) {
            $end_date = gmdate( 'Y-m-d', strtotime( $end_date ) );
        }
        $date_range = $this->get_date_range(
            $days,
            $start_date,
            $end_date,
            $since_start
        );
        $data = $this->get_click_data( $date_range );
        wp_send_json_success( $data );
    }

    /**
     * AJAX handler for retrieving statistics for a specific link.
     */
    public function ajax_get_link_stats() {
        check_ajax_referer( 'linkcentral_admin_nonce', 'nonce' );
        $link_id = ( isset( $_POST['link_id'] ) ? intval( $_POST['link_id'] ) : 0 );
        if ( !$link_id ) {
            wp_send_json_error( 'Invalid link ID' );
            return;
        }
        $days = ( isset( $_POST['days'] ) ? sanitize_text_field( wp_unslash( $_POST['days'] ) ) : 30 );
        $start_date = ( isset( $_POST['start_date'] ) ? sanitize_text_field( wp_unslash( $_POST['start_date'] ) ) : null );
        $end_date = ( isset( $_POST['end_date'] ) ? sanitize_text_field( wp_unslash( $_POST['end_date'] ) ) : null );
        $since_start = ( isset( $_POST['since_start'] ) ? filter_var( $_POST['since_start'], FILTER_VALIDATE_BOOLEAN ) : false );
        if ( $start_date ) {
            $start_date = gmdate( 'Y-m-d', strtotime( $start_date ) );
        }
        if ( $end_date ) {
            $end_date = gmdate( 'Y-m-d', strtotime( $end_date ) );
        }
        $date_range = $this->get_date_range(
            $days,
            $start_date,
            $end_date,
            $since_start,
            $link_id
        );
        $data = $this->get_click_data( $date_range, $link_id );
        wp_send_json_success( $data );
    }

    /**
     * AJAX handler for retrieving statistics for a specific category.
     */
    public function ajax_get_category_stats() {
        check_ajax_referer( 'linkcentral_admin_nonce', 'nonce' );
        $category_id = ( isset( $_POST['category_id'] ) ? intval( $_POST['category_id'] ) : 0 );
        if ( !$category_id ) {
            wp_send_json_error( 'Invalid category ID' );
            return;
        }
        $days = ( isset( $_POST['days'] ) ? sanitize_text_field( wp_unslash( $_POST['days'] ) ) : 30 );
        $start_date = ( isset( $_POST['start_date'] ) ? sanitize_text_field( wp_unslash( $_POST['start_date'] ) ) : null );
        $end_date = ( isset( $_POST['end_date'] ) ? sanitize_text_field( wp_unslash( $_POST['end_date'] ) ) : null );
        $since_start = ( isset( $_POST['since_start'] ) ? filter_var( $_POST['since_start'], FILTER_VALIDATE_BOOLEAN ) : false );
        if ( $start_date ) {
            $start_date = gmdate( 'Y-m-d', strtotime( $start_date ) );
        }
        if ( $end_date ) {
            $end_date = gmdate( 'Y-m-d', strtotime( $end_date ) );
        }
        $date_range = $this->get_date_range(
            $days,
            $start_date,
            $end_date,
            $since_start,
            $category_id
        );
        // Pass category_id to get_date_range
        $data = $this->get_click_data( $date_range, null, $category_id );
        // Pass category_id to get_click_data
        wp_send_json_success( $data );
    }

}
