<?php
/**
 * Created by PhpStorm.
 * User: Zero
 * Date: 2020/8/18
 * Time: 8:13
 */

namespace Meibuyu\Micro\Shopify;

use Exception;
use Meibuyu\Micro\Shopify\lib\AbstractShopify;
use Meibuyu\Micro\Shopify\lib\Collect;
use Meibuyu\Micro\Shopify\lib\Collection;
use Meibuyu\Micro\Shopify\lib\CustomCollection;
use Meibuyu\Micro\Shopify\lib\Event;
use Meibuyu\Micro\Shopify\lib\Fulfillment;
use Meibuyu\Micro\Shopify\lib\FulfillmentService;
use Meibuyu\Micro\Shopify\lib\Graphql;
use Meibuyu\Micro\Shopify\lib\InventoryItem;
use Meibuyu\Micro\Shopify\lib\InventoryLevel;
use Meibuyu\Micro\Shopify\lib\Location;
use Meibuyu\Micro\Shopify\lib\Metafield;
use Meibuyu\Micro\Shopify\lib\Order;
use Meibuyu\Micro\Shopify\lib\Product;
use Meibuyu\Micro\Shopify\lib\ProductVariant;
use Meibuyu\Micro\Shopify\lib\SmartCollection;
use Meibuyu\Micro\Shopify\lib\Webhook;

/**
 * Class ShopifyApp
 * @package Meibuyu\Shopify
 *
 * @property-read Webhook $Webhook
 * @property-read Collect $Collect
 * @property-read Collection $Collection
 * @property-read CustomCollection $CustomCollection
 * @property-read SmartCollection $SmartCollection
 * @property-read Metafield $Metafield
 * @property-read Product $Product
 * @property-read ProductVariant $ProductVariant
 * @property-read InventoryItem $InventoryItem
 * @property-read InventoryLevel $InventoryLevel
 * @property-read Location $Location
 * @property-read Order $Order
 * @property-read Event $Event
 * @property-read Fulfillment $Fulfillment
 * @property-read FulfillmentService $FulfillmentService
 * @property-read GraphQL $GraphQL
 *
 * @method Webhook Webhook(integer $id = null)
 * @method Collection Collection(integer $id = null)
 * @method CustomCollection CustomCollection(integer $id = null)
 * @method SmartCollection SmartCollection(integer $id = null)
 * @method Metafield Metafield(integer $id = null)
 * @method Product Product(integer $id = null)
 * @method ProductVariant ProductVariant(integer $id = null)
 * @method InventoryItem InventoryItem(integer $id = null)
 * @method InventoryLevel InventoryLevel(integer $id = null)
 * @method Location Location(integer $id = null)
 * @method Order Order(integer $id = null)
 * @method Event Event(integer $id = null)
 * @method Fulfillment Fulfillment(integer $id = null)
 * @method FulfillmentService FulfillmentService(integer $id = null)
 * @method GraphQL GraphQL()
 *
 */
class ShopifyApp
{

    protected $resources = [
        'Webhook',
        'Collect',
        'Collection',
        'CustomCollection',
        'SmartCollection',
        'Metafield',
        'Product',
        'ProductVariant',
        'InventoryItem',
        'InventoryLevel',
        'Location',
        'Order',
        'Event',
        'Fulfillment',
        'FulfillmentService',
        'GraphQL',
    ];

    protected $childResources = array(
        'Fulfillment' => 'Order',
        'FulfillmentEvent' => 'Fulfillment',
        'OrderRisk' => 'Order',
        'ProductImage' => 'Product',
        'ProductVariant' => 'Product',
        'DiscountCode' => 'PriceRule',
        'Refund' => 'Order',
        'Transaction' => 'Order',
    );

    public $config = [];

    public $defaultApiVersion = '2020-07';

    /**
     * ShopifyApp constructor.
     * @param array $config
     */
    public function __construct($config)
    {
        $this->config = [
            'api_version' => $this->defaultApiVersion
        ];
        foreach ($config as $key => $value) {
            $this->config[$key] = $value;
        }
        if (isset($config['shop_url'])) {
            $this->setApiUrl();
        }
    }

    /**
     * 返回AbstractShopify实例
     * @param string $className 实现的类名
     * @return AbstractShopify
     * @throws Exception
     */
    public function __get($className)
    {
        return $this->$className();
    }

    /**
     * 返回AbstractShopify实例
     * @param string $className 实现的类名
     * @param $arguments
     * @return AbstractShopify
     * @throws Exception
     */
    public function __call($className, $arguments)
    {
        if (!in_array($className, $this->resources)) {
            if (isset($this->childResources[$className])) {
                $message = "$className 是属于 {$this->childResources[$className]} 的子集, 无法直接访问";
            } else {
                $message = "未知类 $className";
            }
            throw new Exception($message);
        }

        $resourceID = !empty($arguments) ? $arguments[0] : null;
        $resourceClassName = __NAMESPACE__ . "\\lib\\$className";
        return new $resourceClassName($this->config, $resourceID);
    }

    public function setApiUrl()
    {
        $shopUrl = $this->config['shop_url'];
        $shopUrl = preg_replace('#^https?://|/$#', '', $shopUrl);
        $apiVersion = $this->config['api_version'];
        $this->config['api_url'] = "https://$shopUrl/admin/api/$apiVersion/";
    }

}