<?php

namespace CommerceBird\Admin;

use CommerceBird\Admin\Actions\Ajax\ExactOnlineAjax;
use CommerceBird\Admin\Traits\Singleton;

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

final class Cmbird_Acf {
	use Singleton;

	public function __construct() {
		// return if the ACF Class is not available.
		if ( ! class_exists( 'ACF' ) ) {
			return;
		}
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
		add_filter( 'acf/load_field/name=costunit', array( $this, 'cost_units' ), 20 );
		add_filter( 'acf/load_field/name=costcenter', array( $this, 'cost_centers' ), 20 );
		add_filter( 'acf/load_field/name=glaccount', array( $this, 'gl_accounts' ), 20 );
	}

	/**
	 * GL Account custom field customization.
	 */
	public function gl_accounts( $field ): array {
		if ( ! $this->is_order_edit_page() ) {
			return $field;
		}
		$gl_accounts = ExactOnlineAjax::instance()->gl_account_get_options();
		if ( ! is_array( $gl_accounts ) ) {
			$gl_accounts = array();
		}
		return $this->extract_choice( $gl_accounts, $field );
	}

	/**
	 * Cost center custom field customization.
	 */
	public function cost_centers( $field ): array {
		if ( ! $this->is_order_edit_page() ) {
			return $field;
		}
		$cost_centers = ExactOnlineAjax::instance()->cost_center_get_options();
		if ( ! is_array( $cost_centers ) ) {
			$cost_centers = array();
		}
		return $this->extract_choice( $cost_centers, $field );
	}

	/**
	 * Cost Units custom field customization.
	 */
	public function cost_units( $field ): array {
		if ( ! $this->is_order_edit_page() ) {
			return $field;
		}
		$cost_units = ExactOnlineAjax::instance()->cost_unit_get_options();
		if ( ! is_array( $cost_units ) ) {
			$cost_units = array();
		}
		return $this->extract_choice( $cost_units, $field );
	}

	/**
	 * Check if the current page is an order edit page.
	 *
	 * @return boolean
	 */
	private function is_order_edit_page(): bool {
		global $pagenow;

		// Check for the classic post edit screen for orders.
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Admin page detection.
		if ( 'post.php' === $pagenow && isset( $_GET['post'] ) && 'shop_order' === get_post_type( sanitize_text_field( wp_unslash( $_GET['post'] ) ) ) ) {
			return true;
		}

		// Check for the HPOS orders screen.
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Admin page detection.
		if ( 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'wc-orders' === $_GET['page'] && isset( $_GET['action'] ) && 'edit' === $_GET['action'] ) {
			return true;
		}

		return false;
	}

	/**
	 * Register ACF fields for the REST API of WooCommerce Orders.
	 */
	public function register_routes() {
		$exclude_type  = array( 'acf-field-group', 'acf-field' );
		$include_types = array( 'page' );
		$post_types    = array_diff( get_post_types( array( '_builtin' => false ) ), $exclude_type );
		$post_types    = array_merge( $post_types, $include_types );

		array_walk(
			$post_types,
			function ( $post_type ) {
				register_rest_field(
					$post_type,
					'ACF',
					array(
						'get_callback' => function ( $object ) {
							if ( function_exists( 'get_fields' ) ) {
								return get_fields( $object['id'] );
							} else {
								return null;
							}
						},
						'schema'       => null,
					)
				);
			}
		);
	}

	/**
	 * @param array $data - ACF data
	 * @param array $field - ACF field
	 *
	 * @return array
	 */
	private function extract_choice( array $data, array $field ): array {
		if ( $data ) {
			$field['choices'] = array();
			foreach ( $data as $choice ) {
				$field['choices'][ $choice ] = $choice;
			}
		}

		return $field;
	}
}
