<?php
/**
 * Order attribution service for tracking shield detection results on orders.
 *
 * @package Carticy\CheckoutShield\Services
 */

declare(strict_types=1);

namespace Carticy\CheckoutShield\Services;

use WC_Order;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Handles order meta attribution for detection results.
 */
final class OrderAttributionService {

	/**
	 * Meta key for checkout origin.
	 */
	public const META_ORIGIN = '_carticy_checkout_shield_origin';

	/**
	 * Meta key for detection status.
	 */
	public const META_STATUS = '_carticy_checkout_shield_status';

	/**
	 * Meta key for detection signals.
	 */
	public const META_SIGNALS = '_carticy_checkout_shield_signals';

	/**
	 * Stats service for tracking detection events.
	 *
	 * @var StatsService
	 */
	private StatsService $stats_service;

	/**
	 * Current request data to be stored.
	 *
	 * @var array
	 */
	private array $pending_attribution = array();

	/**
	 * Constructor.
	 *
	 * @param StatsService $stats_service Stats service instance.
	 */
	public function __construct( StatsService $stats_service ) {
		$this->stats_service = $stats_service;
	}

	/**
	 * Register hooks.
	 */
	public function register(): void {
		// Hook into order creation for both checkout types.
		add_action( 'woocommerce_checkout_order_processed', array( $this, 'save_attribution' ), 10, 3 );

		// For Store API (Block Checkout), use the Store API specific hook.
		add_action( 'woocommerce_store_api_checkout_order_processed', array( $this, 'save_attribution_store_api' ), 10, 1 );
	}

	/**
	 * Set attribution data to be saved with the next order.
	 *
	 * @param string $origin  The checkout origin (store_api, classic_ajax).
	 * @param string $status  The detection status (passed, blocked, bypassed, learning).
	 * @param array  $signals The detection signals and their results.
	 */
	public function set_attribution( string $origin, string $status, array $signals = array() ): void {
		$this->pending_attribution = array(
			'origin'  => $origin,
			'status'  => $status,
			'signals' => $signals,
		);

		// Record the event in daily stats.
		$this->stats_service->record_event( $status );
	}

	/**
	 * Save attribution data to classic checkout order.
	 *
	 * @param int      $order_id    The order ID.
	 * @param array    $posted_data Posted form data.
	 * @param WC_Order $order       The order object.
	 */
	public function save_attribution( int $order_id, array $posted_data, WC_Order $order ): void {
		// Only save if we have pending attribution and it's for classic checkout.
		if ( empty( $this->pending_attribution ) ) {
			return;
		}

		// Skip if this is a Store API order (will be handled by save_attribution_store_api).
		if ( isset( $this->pending_attribution['origin'] ) && 'store_api' === $this->pending_attribution['origin'] ) {
			return;
		}

		$this->save_order_meta( $order );
	}

	/**
	 * Save attribution data to Store API order.
	 *
	 * @param WC_Order $order The order object.
	 */
	public function save_attribution_store_api( WC_Order $order ): void {
		if ( empty( $this->pending_attribution ) ) {
			return;
		}

		$this->save_order_meta( $order );
	}

	/**
	 * Save meta data to order.
	 *
	 * @param WC_Order $order The order object.
	 */
	private function save_order_meta( WC_Order $order ): void {
		if ( empty( $this->pending_attribution ) ) {
			return;
		}

		$order->update_meta_data( self::META_ORIGIN, $this->pending_attribution['origin'] ?? '' );
		$order->update_meta_data( self::META_STATUS, $this->pending_attribution['status'] ?? '' );
		$order->update_meta_data( self::META_SIGNALS, $this->pending_attribution['signals'] ?? array() );
		$order->save();

		// Clear pending attribution after saving.
		$this->pending_attribution = array();
	}

	/**
	 * Get attribution data from an order.
	 *
	 * @param WC_Order|int $order The order object or ID.
	 * @return array{origin: string, status: string, signals: array}
	 */
	public function get_attribution( $order ): array {
		if ( is_int( $order ) ) {
			$order = wc_get_order( $order );
		}

		if ( ! $order instanceof WC_Order ) {
			return array(
				'origin'  => '',
				'status'  => '',
				'signals' => array(),
			);
		}

		$origin  = $order->get_meta( self::META_ORIGIN );
		$status  = $order->get_meta( self::META_STATUS );
		$signals = $order->get_meta( self::META_SIGNALS );

		return array(
			'origin'  => $origin ? $origin : '',
			'status'  => $status ? $status : '',
			'signals' => $signals ? $signals : array(),
		);
	}

	/**
	 * Get status badge HTML for display.
	 *
	 * @param string $status The detection status.
	 * @return string HTML badge.
	 */
	public function get_status_badge( string $status ): string {
		$badges = array(
			'passed'   => '<span class="ccs-badge ccs-badge--passed">' . esc_html__( 'Passed', 'carticy-checkout-shield-for-woocommerce' ) . '</span>',
			'blocked'  => '<span class="ccs-badge ccs-badge--blocked">' . esc_html__( 'Blocked', 'carticy-checkout-shield-for-woocommerce' ) . '</span>',
			'bypassed' => '<span class="ccs-badge ccs-badge--bypassed">' . esc_html__( 'Bypassed', 'carticy-checkout-shield-for-woocommerce' ) . '</span>',
			'learning' => '<span class="ccs-badge ccs-badge--learning">' . esc_html__( 'Learning', 'carticy-checkout-shield-for-woocommerce' ) . '</span>',
		);

		return $badges[ $status ] ?? '<span class="ccs-badge ccs-badge--unknown">—</span>';
	}
}
