<?php
/**
 * @package Hafenstudios\Kurato
 */

namespace Hafenstudios\Kurato\Rest;

use Hafenstudios\Kurato\Campaign\CampaignStats;
use Hafenstudios\Kurato\Db\CampaignRepository;
use Hafenstudios\Kurato\Db\MailEventRepository;
use Hafenstudios\Kurato\Db\QueueRepository;
use Hafenstudios\Kurato\Insight\FunnelAnalytics;

defined( 'ABSPATH' ) || exit;

/**
 * REST: Kennzahlen fuer den Cockpit-Screen "Statistik" (`kurato/v1/insight`, CP4).
 *
 * Liefert ausschliesslich vorhandene H2-/K4e-Datenbasis: den Funnel-Bericht aus
 * {@see FunnelAnalytics::report()} und die Kampagnen-Kennzahlen aus
 * {@see CampaignStats::summarize()}. **Keine neue Rechenlogik** - dieser
 * Controller ist reine Auslieferung. Damit gilt die Ehrlichkeits-Linie (K4e)
 * unveraendert weiter: Raten tragen ihre Basis, ohne Basis steht `null`, und
 * Oeffnungen/Klicks erscheinen nur mit der Bezugsgroesse `consented`.
 *
 * Lesen erfordert hs_view_contacts (Muster ContactsController).
 */
final class InsightController extends AbstractController {

	public const REST_NAMESPACE = 'kurato/v1';

	/** Wie viele Kampagnen die Statistik hoechstens ausweist (neueste zuerst). */
	private const MAX_CAMPAIGNS = 5;

	private FunnelAnalytics $funnel;

	private CampaignRepository $campaigns;

	private QueueRepository $queue;

	private MailEventRepository $events;

	private bool $tracking_enabled;

	/**
	 * @param FunnelAnalytics     $funnel           Funnel-Analytik (H2).
	 * @param CampaignRepository  $campaigns        Kampagnen-Repository.
	 * @param QueueRepository     $queue            Versand-Queue (Server-Fakten).
	 * @param MailEventRepository $events           Mail-Ereignisse.
	 * @param bool                $tracking_enabled Site-Schalter tracking.enabled.
	 */
	public function __construct(
		FunnelAnalytics $funnel,
		CampaignRepository $campaigns,
		QueueRepository $queue,
		MailEventRepository $events,
		bool $tracking_enabled
	) {
		$this->funnel           = $funnel;
		$this->campaigns        = $campaigns;
		$this->queue            = $queue;
		$this->events           = $events;
		$this->tracking_enabled = $tracking_enabled;
	}

	/**
	 * Registriert die Route.
	 *
	 * @return void
	 */
	public function register_routes(): void {
		register_rest_route(
			self::REST_NAMESPACE,
			'/insight',
			array(
				'methods'             => \WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_insight' ),
				'permission_callback' => array( $this, 'can_view' ),
				'args'                => array(
					'days' => array( 'type' => 'integer', 'default' => FunnelAnalytics::RANGES[0] ),
				),
			)
		);
	}

	/**
	 * GET /insight - Funnel-Bericht plus Kampagnen-Kennzahlen.
	 *
	 * @param \WP_REST_Request $request Request.
	 * @return \WP_REST_Response
	 */
	public function get_insight( \WP_REST_Request $request ): \WP_REST_Response {
		$days = FunnelAnalytics::normalize_days( (int) $request->get_param( 'days' ) );

		return new \WP_REST_Response(
			array(
				'funnel'    => $this->funnel->report( $days ),
				'campaigns' => $this->campaign_rows(),
				'ranges'    => FunnelAnalytics::RANGES,
			),
			200
		);
	}

	/**
	 * Kennzahlen der juengsten Kampagnen (nur bereits gestartete tragen eine
	 * aussagekraeftige Statistik, Muster CampaignsPage).
	 *
	 * @return array<int, array<string, mixed>>
	 */
	private function campaign_rows(): array {
		$out  = array();
		$page = $this->campaigns->all( 1, self::MAX_CAMPAIGNS );
		foreach ( $page['items'] as $campaign ) {
			$id = (int) $campaign['id'];
			if ( ! in_array( (string) $campaign['status'], array( 'sending', 'paused', 'sent', 'aborted' ), true ) ) {
				continue;
			}
			$stats = CampaignStats::summarize(
				$this->queue->counts_for_campaign( $id ),
				$this->events->counts_for_campaign( $id ),
				$this->tracking_enabled,
				$this->tracking_enabled ? $this->queue->tracking_consented_count( $id ) : 0
			);

			$out[] = array_merge(
				array(
					'id'               => $id,
					'title'            => get_the_title( (int) $campaign['post_id'] ),
					'status'           => (string) $campaign['status'],
					'total_recipients' => (int) $campaign['total_recipients'],
					'started_at'       => (string) $campaign['started_at'],
				),
				$stats
			);
		}
		return $out;
	}
}
