<?php

namespace WcElectronInvoice\Providers;

defined('ABSPATH') || die('Not allowed.');

class OrderQuery
{

    /**
     * @var OrdersProviderAbstract[]
     */
    private $ordersProviders = [];

    /**
     * @var OrderQuery $instance
     *
     */
    private static $instance;

    /**
     * Get all orders from all providers
     *
     * @param array $args
     *
     * @return OrderAbstract[]
     */
    public function getProvidersOrders(array $args = array())
    {
	    if ( ! empty( $args['limit'] ) && $args['limit'] == - 1 ) {
		    $args['limit'] = apply_filters( 'wc_el_inv-list-orders-limit-max', 500 );
	    }
		
        $orders = array();

        foreach ($this->ordersProviders as $provider) {
            if (! empty($args['provider']) && 'all' !== $args['provider']) {
                if ($provider->name() !== $args['provider']) {
                    continue;
                }
            }

            foreach ($provider->getOrders($args) as $order) {
				$orders[] = $order;
            }
        }

        return $orders;
    }

    /**
     * Get normalized document summaries from all eligible providers.
     *
     * @param array $args
     *
     * @return array<int, array<string, mixed>>
     */
    public function getProvidersOrderSummaries(array $args = array())
    {
        if (! empty($args['limit']) && $args['limit'] == -1) {
            $args['limit'] = apply_filters('wc_el_inv-list-orders-limit-max', 500);
        }

        $summaries = array();

        foreach ($this->ordersProviders as $provider) {
            if (! empty($args['provider']) && 'all' !== $args['provider']) {
                if ($provider->name() !== $args['provider']) {
                    continue;
                }
            }

            foreach ($provider->getOrderSummaries($args) as $summary) {
                $summaries[] = $summary;
            }
        }

        return $summaries;
    }

    /**
     * Get order by id and provider name
     *
     * @param int $order_id
     * @param string|OrdersProviderAbstract $provider
     *
     * @return OrderAbstract|null
     */
    public function getProviderOrder($order_id, $provider)
    {
	    if ( empty( $provider ) ) {
		    throw new \Exception( 'POP: Provider name is required' );
	    }
		
		if( is_string( $provider ) ){
			$provider = $this->get_provider( $provider );
		}

	    if ( $provider ) {
		    return $provider->getOrder( $order_id );
	    }
		
        return null;
    }

    /**
     * Return a single instance of OrderQuery
     *
     * @return OrderQuery
     */
    public static function instance()
    {
        if (! isset(self::$instance)) {
            self::$instance = new OrderQuery();
        }

        return self::$instance;
    }

    /**
     * Register a data provider
     *
     * @param OrdersProviderAbstract $provider
     *
     * @return void
     */
    public function register_provider($provider)
    {
	    $this->ordersProviders[ $provider->name() ] = $provider;
    }

    /**
     * Return providers list
     *
     * @return OrdersProviderAbstract[]
     */
    public function get_providers()
    {
        return $this->ordersProviders;
    }

	/**
	 * Return a single provider
	 * 
	 * @param string $provider_name
	 *
	 * @return OrdersProviderAbstract|null
	 */
	public function get_provider( $provider_name ){
		return $this->ordersProviders[ $provider_name ] ?? null;
	}

}
