<?php
/**
 * Fraud Graph for Reports
 *
 * @package     AffiliateWP
 * @subpackage  Admin/Reports
 * @copyright   Copyright (c) 2025, Awesome Motive Inc
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       2.28.0
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

#[\AllowDynamicProperties]

/**
 * Fraud graph class for the Reports screen.
 *
 * @since 2.28.0
 */
class Affiliate_WP_Fraud_Graph extends Affiliate_WP_Graph {

	/**
	 * Get things started.
	 *
	 * @since 2.28.0
	 *
	 * @param array $_data Optional. Graph data.
	 */
	public function __construct( $_data = array() ) {

		// Generate unique ID.
		$this->id = md5( rand() );

		// Setup default options.
		$this->options = array(
			'y_mode'          => null,
			'y_decimals'      => 0,
			'x_decimals'      => 0,
			'y_position'      => 'right',
			'time_format'     => '%d/%b',
			'ticksize_unit'   => 'day',
			'ticksize_num'    => 1,
			'multiple_y_axes' => false,
			'bgcolor'         => '#f9f9f9',
			'bordercolor'     => '#ccc',
			'color'           => '#bbb',
			'borderwidth'     => 2,
			'bars'            => false,
			'lines'           => true,
			'points'          => true,
			'affiliate_id'    => false,
			'show_controls'   => true,
			'form_wrapper'    => true,
			'currency'        => false, // Fraud graph shows counts, not amounts.
		);
	}

	/**
	 * Retrieve fraud data for the graph.
	 *
	 * Shows rejected referrals, flagged referrals, and flagged visits over time.
	 *
	 * @since 2.28.0
	 *
	 * @return array Graph data.
	 */
	public function get_data() {

		$rejected_referrals = array();
		$flagged_referrals  = array();
		$flagged_visits     = array();

		$dates = affwp_get_report_dates();

		$start = $dates['year'] . '-' . $dates['m_start'] . '-' . $dates['day'];
		$end   = $dates['year_end'] . '-' . $dates['m_end'] . '-' . $dates['day_end'];

		$date = array(
			'start' => $start,
			'end'   => $end,
		);

		$difference = ( strtotime( $date['end'] ) - strtotime( $date['start'] ) );

		// Get rejected referrals.
		$rejected = affiliate_wp()->referrals->get_referrals(
			array(
				'orderby'      => 'date',
				'order'        => 'ASC',
				'date'         => $date,
				'number'       => -1,
				'status'       => 'rejected',
				'affiliate_id' => $this->get( 'affiliate_id' ),
			)
		);

		// Get flagged referrals (pending with flags).
		$flagged = affiliate_wp()->referrals->get_referrals(
			array(
				'orderby'      => 'date',
				'order'        => 'ASC',
				'date'         => $date,
				'number'       => -1,
				'status'       => 'pending',
				'flag'         => array( 'self_referral', 'ppc_traffic', 'conversion_rate', 'referring_site' ),
				'affiliate_id' => $this->get( 'affiliate_id' ),
			)
		);

		// Get flagged visits.
		$visits = affiliate_wp()->visits->get_visits(
			array(
				'orderby'      => 'date',
				'order'        => 'ASC',
				'date'         => $date,
				'number'       => -1,
				'flag'         => array( 'ppc_traffic', 'referring_site' ),
				'affiliate_id' => $this->get( 'affiliate_id' ),
			)
		);

		// Add start and end points for the graph.
		$rejected_referrals[] = array( strtotime( $start ) * 1000 );
		$rejected_referrals[] = array( strtotime( $end ) * 1000 );
		$flagged_referrals[]  = array( strtotime( $start ) * 1000 );
		$flagged_referrals[]  = array( strtotime( $end ) * 1000 );
		$flagged_visits[]     = array( strtotime( $start ) * 1000 );
		$flagged_visits[]     = array( strtotime( $end ) * 1000 );

		// Process rejected referrals.
		if ( $rejected ) {
			$totals = array();

			foreach ( $rejected as $referral ) {
				if ( in_array( $dates['range'], array( 'this_year', 'last_year' ), true )
					|| $difference >= YEAR_IN_SECONDS
				) {
					$referral_date = date( 'Y-m', strtotime( $referral->date ) );
				} else {
					$referral_date = date( 'Y-m-d', strtotime( $referral->date ) );
				}

				if ( empty( $totals[ $referral_date ] ) ) {
					$totals[ $referral_date ] = 1;
				} else {
					$totals[ $referral_date ]++;
				}
			}

			foreach ( $totals as $referral_date => $count ) {
				$rejected_referrals[] = array( strtotime( $referral_date ) * 1000, $count );
			}
		}

		// Process flagged referrals.
		if ( $flagged ) {
			$totals = array();

			foreach ( $flagged as $referral ) {
				if ( in_array( $dates['range'], array( 'this_year', 'last_year' ), true )
					|| $difference >= YEAR_IN_SECONDS
				) {
					$referral_date = date( 'Y-m', strtotime( $referral->date ) );
				} else {
					$referral_date = date( 'Y-m-d', strtotime( $referral->date ) );
				}

				if ( empty( $totals[ $referral_date ] ) ) {
					$totals[ $referral_date ] = 1;
				} else {
					$totals[ $referral_date ]++;
				}
			}

			foreach ( $totals as $referral_date => $count ) {
				$flagged_referrals[] = array( strtotime( $referral_date ) * 1000, $count );
			}
		}

		// Process flagged visits.
		if ( $visits ) {
			$totals = array();

			foreach ( $visits as $visit ) {
				if ( in_array( $dates['range'], array( 'this_year', 'last_year' ), true )
					|| $difference >= YEAR_IN_SECONDS
				) {
					$visit_date = date( 'Y-m', strtotime( $visit->date ) );
				} else {
					$visit_date = date( 'Y-m-d', strtotime( $visit->date ) );
				}

				if ( empty( $totals[ $visit_date ] ) ) {
					$totals[ $visit_date ] = 1;
				} else {
					$totals[ $visit_date ]++;
				}
			}

			foreach ( $totals as $visit_date => $count ) {
				$flagged_visits[] = array( strtotime( $visit_date ) * 1000, $count );
			}
		}

		$data = array(
			__( 'Rejected Referrals', 'affiliate-wp' ) => $rejected_referrals,
			__( 'Flagged Referrals', 'affiliate-wp' )  => $flagged_referrals,
			__( 'Flagged Visits', 'affiliate-wp' )     => $flagged_visits,
		);

		return $data;
	}
}
