<?php
/**
 * Conversion Funnel Chart
 *
 * @package     EDD\Pro\CartRecovery\Admin\Reports\Endpoints\Charts
 * @copyright   Copyright (c) 2026, Sandhills Development, LLC
 * @license     https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       3.6.5
 */

namespace EDD\Pro\CartRecovery\Admin\Reports\Endpoints\Charts;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

use EDD\Reports\Endpoints\Charts\Bar;
use EDD\Pro\CartRecovery\Journey\Repository;

/**
 * Conversion Funnel Chart class.
 *
 * Displays funnel visualization showing drop-off at each stage.
 *
 * @since 3.6.5
 */
class ConversionFunnel extends Bar {

	/**
	 * Journey repository.
	 *
	 * @var Repository
	 */
	private $journey_repo;

	/**
	 * The funnel stages data.
	 *
	 * @since 3.6.5
	 * @var array
	 */
	private $stages_data = array();

	/**
	 * Constructor.
	 *
	 * @since 3.6.5
	 * @param \EDD\Reports\Data\Report_Registry $reports Reports registry.
	 */
	public function __construct( $reports ) {
		$this->journey_repo = new Repository();
		parent::__construct( $reports );
	}

	/**
	 * Gets the chart endpoint ID.
	 *
	 * @since 3.6.5
	 * @return string
	 */
	protected function get_id(): string {
		return 'acr_conversion_funnel_chart';
	}

	/**
	 * Gets the chart label for display.
	 *
	 * @since 3.6.5
	 * @return string
	 */
	protected function get_label(): string {
		return __( 'Customer Journey Funnel', 'easy-digital-downloads' );
	}

	/**
	 * Gets the query results for the funnel chart.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	protected function get_query_results(): array {
		// Get date range from the dates property.
		$start_date = $this->dates['start']->copy()->format( 'Y-m-d' );
		$end_date   = $this->dates['end']->copy()->format( 'Y-m-d' );

		// Get funnel metrics.
		$metrics = $this->journey_repo->get_funnel_metrics( $start_date, $end_date );

		$stages = $metrics['stages'];

		// Store the stages data for use in building the chart.
		// Order must match the labels array.
		$this->stages_data = array(
			(int) $stages['created'],
			(int) $stages['abandoned'],
			(int) $stages['sent'],
			(int) $stages['opened'],
			(int) $stages['clicked'],
			(int) $stages['restored'],
			(int) $stages['converted'],
		);

		// Return empty array since we're not using time-based data.
		return array();
	}

	/**
	 * Gets the chart datasets configuration.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	protected function get_datasets(): array {
		return array(
			'funnel' => array(
				'label'           => __( 'Count', 'easy-digital-downloads' ),
				'backgroundColor' => $this->get_funnel_colors(),
				'borderColor'     => $this->get_funnel_colors(),
				'borderWidth'     => 1,
				'type'            => 'number',
			),
		);
	}

	/**
	 * Gets the colors for the funnel bars.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	private function get_funnel_colors(): array {
		$color_keys = array( 'blue', 'green', 'yellow', 'orange', 'red', 'purple', 'indigo' );
		$colors     = array();

		foreach ( $color_keys as $key ) {
			if ( isset( $this->colors[ $key ] ) ) {
				$colors[] = "rgba({$this->colors[$key]},0.8)";
			}
		}

		return $colors;
	}

	/**
	 * Initializes the data for a specific timestamp.
	 *
	 * @since 3.6.5
	 * @param int    $timestamp     Unix timestamp.
	 * @param object $date_on_chart Current chart date.
	 */
	protected function initialize_timestamp_data( $timestamp, $date_on_chart ): void {
		// Not used for this funnel chart as it's not time-based.
	}

	/**
	 * Processes query results for a specific timestamp.
	 *
	 * @since 3.6.5
	 * @param array  $query_results All query results.
	 * @param int    $timestamp     Unix timestamp.
	 * @param object $date_on_chart Current chart date.
	 */
	protected function process_query_results( array $query_results, $timestamp, $date_on_chart ): void {
		// Not used for this funnel chart as it's not time-based.
	}

	/**
	 * Formats the data for output.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	protected function format_data(): array {
		return array(
			'funnel' => $this->stages_data,
		);
	}

	/**
	 * Gets the chart options for the bar chart.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	protected function get_chart_options(): array {
		return array(
			'datasets' => $this->get_datasets(),
			'labels'   => $this->get_labels(),
			'scales'   => array(
				'yAxes' => array(
					array(
						'type'      => 'linear',
						'display'   => true,
						'ticks'     => array(
							'beginAtZero' => true,
							'precision'   => 0,
						),
						'gridLines' => array(
							'display' => true,
						),
					),
				),
				'xAxes' => array(
					array(
						'type'      => 'category',
						'display'   => true,
						'gridLines' => array(
							'display' => false,
						),
					),
				),
			),
		);
	}

	/**
	 * Gets the labels for the chart.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	private function get_labels(): array {
		return array(
			__( 'Carts Created', 'easy-digital-downloads' ),
			__( 'Abandoned', 'easy-digital-downloads' ),
			__( 'Emails Sent', 'easy-digital-downloads' ),
			__( 'Emails Opened', 'easy-digital-downloads' ),
			__( 'Emails Clicked', 'easy-digital-downloads' ),
			__( 'Carts Restored', 'easy-digital-downloads' ),
			__( 'Carts Recovered', 'easy-digital-downloads' ),
		);
	}

	/**
	 * Gets the chart data.
	 *
	 * This override is needed because the funnel chart is not time-based.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	protected function get_data(): array {
		try {
			$this->get_query_results();
			return $this->format_data();
		} catch ( \Exception $e ) {
			edd_debug_log( $e->getMessage(), true );
			return array();
		}
	}
}
