<?php

namespace Simplyin\Simplyin_W_Plugin\Payments\Ajax\Card;

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

use Simplyin\Simplyin_W_Plugin\Payments\Gateway\Model\Order_Data;
use Simplyin\Simplyin_W_Plugin\Payments\Gateway\Status\Payment_Status;

class Card_Ajax_Handler {

	public function register_ajax_hooks() {

		add_action(
			'wp_ajax_simplyin_get_card_payment_status',
			[
				$this,
				'action_get_card_payment_status',
			]
		);
		add_action(
			'wp_ajax_nopriv_simplyin_get_card_payment_status',
			[
				$this,
				'action_get_card_payment_status',
			]
		);

		add_action(
			'wp_ajax_simplyin_card_payment_timeout',
			[
				$this,
				'action_card_payment_timeout',
			]
		);
		add_action(
			'wp_ajax_nopriv_simplyin_card_payment_timeout',
			[
				$this,
				'action_card_payment_timeout',
			]
		);
	}


	public function action_get_card_payment_status(): void {
		if ( isset( $_POST['ajax_token'] ) && wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_POST['ajax_token'] ) ),
				'simplyin_card_status'
			) ) {

			if ( isset( $_POST['order_id'] ) ) {
				$order_id = (int) sanitize_text_field( wp_unslash( $_POST['order_id'] ) );
			} else {
				$this->output_response_bad_request();
				return;
			}

			$ajax_response = new Card_Get_Status_Ajax_Response();

			$order = wc_get_order( $order_id );
			if ( ! $order ) {
				$this->output_response_bad_request();
				return;
			}

			$this->order_data = new Order_Data( $order );

			$payment = $this->order_data->get_selected_payment_type();
			if ( $error_message = $payment->get_customer_error_message() ) {
				$ajax_response->set_payment_status_failure();
				$ajax_response->set_customer_error_message( $error_message );
				$ajax_response->send_json_exit();
			}

			$payment_status_service = new Payment_Status( $this->order_data );
			$payment_status         = $payment_status_service->get_payment_status_remote();

			// Debug log AJAX snapshot
			try {
				simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
					sprintf(
						'[card_status_ajax] order_id=%s status=%s',
						esc_html( (string) $order_id ),
						esc_html( (string) $payment_status )
					),
					'payments'
				);
			} catch ( \Throwable $e ) {
				// noop
			}

			if ( $payment_status === Payment_Status::STATUS_PAID ) {
				$ajax_response->set_payment_status_success();
				$ajax_response->send_json_exit();
				// todo set flag to block query this order
			}

			if ( $payment_status === Payment_Status::STATUS_PENDING ) {

				$ajax_response->set_payment_status_pending();
				$ajax_response->send_json_exit();
			}

			$ajax_response->set_payment_status_failure();
			$ajax_response->send_json_exit();
		}

		$this->output_response_unauthorized();
		return;
	}

	public function action_card_payment_timeout(): void {
		if ( ! ( isset( $_POST['ajax_token'] ) && wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_POST['ajax_token'] ) ),
				'simplyin_card_status'
			) ) ) {
			$this->output_response_unauthorized();
			return;
		}

		if ( ! isset( $_POST['order_id'] ) ) {
			$this->output_response_bad_request();
			return;
		}

		$order_id = (int) sanitize_text_field( wp_unslash( $_POST['order_id'] ) );
		$order    = wc_get_order( $order_id );
		if ( ! $order ) {
			$this->output_response_bad_request();
			return;
		}

		if ( ! WC()->session ) {
			$this->output_response_unauthorized();
			return;
		}

		$session_order_id = (int) WC()->session->get( 'order_awaiting_payment' );
		if ( 0 === $session_order_id || $session_order_id !== $order_id ) {
			$this->output_response_unauthorized();
			return;
		}

		$order_data = new Order_Data( $order );
		$order->delete_meta_data( '_simplyin_payment_timeout_failed' );
		$order->save();
		$payment_uuid = '';
		if ( isset( $_POST['payment_uuid'] ) ) {
			$payment_uuid = (string) sanitize_text_field( wp_unslash( $_POST['payment_uuid'] ) );
		}
		if ( $payment_uuid === '' ) {
			try {
				$payment_uuid = (string) ( $order_data->get_selected_payment_type()->get_payment_uuid() ?? '' );
			} catch ( \Throwable $e ) {
				$payment_uuid = '';
			}
		}
		if ( $payment_uuid !== '' ) {
			$order->update_meta_data( '_simplyin_payment_timeout_failed_payment_uuid', $payment_uuid );
			$order->save();
		}

		try {
			$payment_status_service = new Payment_Status( $order_data );
			$remote_status          = $payment_status_service->get_payment_status_remote();
			if ( $remote_status === Payment_Status::STATUS_PAID ) {
				wp_send_json( [ 'timeout_failed' => false ] );
				die;
			}
		} catch ( \Throwable $e ) {
			simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
				sprintf( '[Card_Ajax_Handler] [timeout] [remote_status] %s: %s', get_class( $e ), $e->getMessage() ),
				'card-timeout'
			);
		}

		$current_status = (string) $order->get_status();
		if ( ! in_array( $current_status, [ 'completed', 'refunded', 'cancelled' ], true ) ) {
			try {
				( new Payment_Status( $order_data ) )->update_payment_status( Payment_Status::STATUS_CANCELED );
			} catch ( \Throwable $e ) {
				simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
					sprintf( '[Card_Ajax_Handler] [timeout] [update_status] %s: %s', get_class( $e ), $e->getMessage() ),
					'card-timeout'
				);
			}

			try {
				$order_data->update_order_status( 'wc-failed', 'Simply.IN payment status timeout. Order marked as failed.' );
			} catch ( \Throwable $e ) {
				simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
					sprintf( '[Card_Ajax_Handler] [timeout] [order_status] %s: %s', get_class( $e ), $e->getMessage() ),
					'card-timeout'
				);
			}
		}

		wp_send_json( [ 'timeout_failed' => true ] );
		die;
	}


	private function output_response_bad_request() {
		header( 'HTTP/1.1 400 BAD REQUEST' );
		exit;
	}

	private function output_response_unauthorized() {
		header( 'HTTP/1.1 401 Unauthorized' );
		exit;
	}
}
