<?php

namespace DigitalApps\PaymentsForAdyen;

defined('ABSPATH') || exit;

/** Shared Checkout API result model for Classic, Blocks, and action details. */
final class Adyen_Result
{
	const ACTION = 'action';
	const AUTHORISED = 'authorised';
	const PENDING = 'pending';
	const REFUSED = 'refused';
	const CANCELLED = 'cancelled';
	const ERROR = 'error';
	const UNKNOWN = 'unknown';

	/** Classify a Checkout API response without exposing internal fields. */
	public static function classify($response)
	{
		if (!is_array($response) || !empty($response['error'])) {
			return self::ERROR;
		}
		if (!empty($response['action']) && is_array($response['action'])) {
			return self::ACTION;
		}

		switch ((string) ($response['resultCode'] ?? '')) {
			case 'Authorised':
				return self::AUTHORISED;
			case 'Pending':
			case 'Received':
				return self::PENDING;
			case 'Refused':
				return self::REFUSED;
			case 'Cancelled':
				return self::CANCELLED;
			case 'Error':
				return self::ERROR;
			default:
				return self::UNKNOWN;
		}
	}

	/** Apply a payment result consistently to a WooCommerce order. */
	public static function apply_to_order($order, array $response, $capture_mode)
	{
		$classification = self::classify($response);
		$psp_reference = sanitize_text_field($response['pspReference'] ?? '');

		if ('' !== $psp_reference && '' === (string) $order->get_transaction_id()) {
			$order->set_transaction_id($psp_reference);
		}

		switch ($classification) {
			case self::ACTION:
				if (!$order->has_status('pending')) {
					$order->update_status('pending', __('Adyen requires the shopper to complete payment authentication.', 'digital-apps-payments-for-adyen'));
				}
				break;
			case self::AUTHORISED:
				if ('manual' === $capture_mode) {
					if (!$order->has_status('on-hold')) {
						$order->update_status('on-hold', __('Payment authorized by Adyen, awaiting manual capture.', 'digital-apps-payments-for-adyen'));
					}
				} elseif (!$order->is_paid() && !$order->has_status(['cancelled', 'refunded', 'on-hold'])) {
					$order->update_status('on-hold', __('Adyen authorized the card payment. Awaiting the signed AUTHORISATION webhook before completing the order.', 'digital-apps-payments-for-adyen'));
				}
				break;
			case self::PENDING:
				if (!$order->is_paid() && !$order->has_status(['cancelled', 'refunded', 'on-hold'])) {
					$order->update_status('on-hold', __('Adyen accepted the payment and final confirmation is pending.', 'digital-apps-payments-for-adyen'));
				}
				break;
			case self::REFUSED:
			case self::CANCELLED:
			case self::ERROR:
			case self::UNKNOWN:
				if (!$order->is_paid() && !$order->has_status(['cancelled', 'refunded', 'failed'])) {
					$order->update_status('failed', __('The Adyen card payment was not completed.', 'digital-apps-payments-for-adyen'));
				}
				break;
		}

		$order->save();
		return $classification;
	}

	/** Return a shopper-safe message for a classified result. */
	public static function shopper_message($classification)
	{
		switch ($classification) {
			case self::REFUSED:
				return __('Your payment could not be approved. Please try another payment method.', 'digital-apps-payments-for-adyen');
			case self::CANCELLED:
				return __('Payment authentication was cancelled. Please try again.', 'digital-apps-payments-for-adyen');
			case self::PENDING:
				return __('Your payment is being confirmed.', 'digital-apps-payments-for-adyen');
			default:
				return __('Payment processing failed. Please try again.', 'digital-apps-payments-for-adyen');
		}
	}

	/** Return only the fields Adyen Web needs to continue its action lifecycle. */
	public static function public_response(array $response)
	{
		$public = ['resultCode' => sanitize_text_field($response['resultCode'] ?? 'Error')];
		if (!empty($response['action']) && is_array($response['action'])) {
			$public['action'] = $response['action'];
		}
		return $public;
	}
}
