<?php

namespace YooMoney\Helpers\OauthHelpers;

use Exception;
use YooKassa\Client;
use YooMoney\Helpers\YookassaClientFactory;

/**
 * Класс методов для получения информации о магазине
 */
class YookassaShopInfoHelper implements YookassaShopInfoHelperInterface
{
    const SHOP_INFO_ACCOUNT_ID = 'account_id';
    const SHOP_INFO_TEST = 'test';
    const SHOP_INFO_FISCALIZATION_ENABLED = 'fiscalization_enabled';

    /*** @var YookassaClientFactory */
    private $clientFactory;

    public function __construct(YookassaClientFactory $clientFactory)
    {
        $this->clientFactory = $clientFactory;
    }

    /**
     * Подключение и получение информации о магазине
     *
     * @return array
     * @throws Exception
     */
    public function fetchShopInfo()
    {
        $client = $this->clientFactory->getClient();
        $shopInfo = $this->tryGetShopInfo($client);
        return $this->checkShopInfo($shopInfo);
    }

    /**
     * Проверка на подключение и получение информации о магазине по токену
     *
     * @param string $token
     * @return array
     * @throws Exception
     */
    public function fetchShopInfoWithGivenToken($token)
    {
        $client = $this->clientFactory->getClientWithGivenToken($token);
        $shopInfo = $this->tryGetShopInfo($client);
        return $this->checkShopInfo($shopInfo);
    }

    /**
     * Попытка получить информацию о магазине
     *
     * @param Client $client
     * @return array|null
     * @throws Exception
     */
    private function tryGetShopInfo($client)
    {
        try {
            return $client->me();
        } catch (\Exception $e) {
            throw new Exception('Failed to get information about shop. ' . $e->getMessage());
        }
    }

    /**
     * Проверка на наличие обязательных параметров в информации о магазине
     *
     * @return array
     * @throws Exception
     */
    private function checkShopInfo($shopInfo)
    {
        if (!isset(
            $shopInfo[self::SHOP_INFO_ACCOUNT_ID],
            $shopInfo[self::SHOP_INFO_TEST],
            $shopInfo[self::SHOP_INFO_FISCALIZATION_ENABLED])
        ) {
            throw new Exception('Information about shop is empty!');
        }

        return $shopInfo;
    }

    /**
     * Получение account_id
     *
     * @param string $token
     * @return string
     * @throws Exception
     */
    public function fetchShopIdWithGivenToken($token)
    {
        $shopInfo = $this->fetchShopInfoWithGivenToken($token);
        return $shopInfo[self::SHOP_INFO_ACCOUNT_ID];
    }
}