<?php
/**
 * Minimal stand-ins for the Magento framework classes/interfaces this module depends on.
 *
 * This repository ships only the TbiBank\FusionPay module source (no `vendor/magento/*`), so
 * there is no real Magento codebase to autoload against for unit tests. Each stub below
 * reproduces ONLY the method surface FusionPay actually calls (verified against the real
 * source files under TbiBank/FusionPay) — enough for PHPUnit to load, type-check and mock the
 * real Magento symbols our classes are constructed with. None of this is a redistribution of
 * Magento code; every stub is written from scratch to match the public method signatures used.
 *
 * Guarded with class_exists()/interface_exists() so this file is harmless to include even in an
 * environment where the real magento/framework packages are present.
 */

namespace Magento\Framework\App {

    if (!class_exists(ResourceConnection::class)) {
        class ResourceConnection
        {
            public function getConnection($resourceName = 'default')
            {
            }

            public function getTableName($modelEntity)
            {
            }
        }
    }
}

namespace Magento\Framework\DB\Adapter {

    if (!interface_exists(AdapterInterface::class)) {
        interface AdapterInterface
        {
            public function update($tableName, array $bind, $where = '');

            public function query($sql, $bind = []);

            public function quoteIdentifier($ident, $auto = false);

            public function addColumn($tableName, $columnName, $definition, $schemaName = null);

            public function tableColumnExists($tableName, $columnName, $schemaName = null);

            public function dropColumn($tableName, $columnName, $schemaName = null);
        }
    }
}

namespace Magento\Framework\DB\Ddl {

    if (!class_exists(Table::class)) {
        class Table
        {
            const TYPE_TEXT = 'text';
            const TYPE_INTEGER = 'integer';
            const TYPE_SMALLINT = 'smallint';
            const TYPE_BOOLEAN = 'boolean';
        }
    }
}

namespace Magento\Framework\Event {

    if (!class_exists(Event::class)) {
        class Event
        {
            /** @var mixed */
            private $order;

            /** @var mixed */
            private $request;

            public function setOrder($order): self
            {
                $this->order = $order;
                return $this;
            }

            public function getOrder()
            {
                return $this->order;
            }

            public function setRequest($request): self
            {
                $this->request = $request;
                return $this;
            }

            public function getRequest()
            {
                return $this->request;
            }
        }
    }

    if (!class_exists(Observer::class)) {
        class Observer
        {
            /** @var Event */
            private $event;

            public function setEvent(Event $event): self
            {
                $this->event = $event;
                return $this;
            }

            public function getEvent(): Event
            {
                return $this->event;
            }
        }
    }

    if (!interface_exists(ObserverInterface::class)) {
        interface ObserverInterface
        {
            public function execute(Observer $observer);
        }
    }
}

namespace Magento\Sales\Api\Data {

    if (!interface_exists(OrderInterface::class)) {
        interface OrderInterface
        {
        }
    }
}

namespace Magento\Sales\Api {

    if (!interface_exists(OrderRepositoryInterface::class)) {
        interface OrderRepositoryInterface
        {
            public function get($id);

            public function save(\Magento\Sales\Api\Data\OrderInterface $entity);

            public function delete(\Magento\Sales\Api\Data\OrderInterface $entity);
        }
    }
}

namespace Magento\Framework\App\Config {

    if (!interface_exists(ScopeConfigInterface::class)) {
        interface ScopeConfigInterface
        {
            public function getValue($path, $scopeType = 'default', $scopeCode = null);

            public function isSetFlag($path, $scopeType = 'default', $scopeCode = null);
        }
    }
}

namespace Magento\Store\Model {

    if (!interface_exists(ScopeInterface::class)) {
        interface ScopeInterface
        {
            const SCOPE_STORE = 'stores';
            const SCOPE_STORES = 'stores';
            const SCOPE_WEBSITE = 'websites';
            const SCOPE_WEBSITES = 'websites';
            const SCOPE_GROUP = 'groups';
            const SCOPE_GROUPS = 'groups';
            const SCOPE_DEFAULT = 'default';
        }
    }

    if (!interface_exists(StoreManagerInterface::class)) {
        interface StoreManagerInterface
        {
            public function getStore($storeId = null);
        }
    }
}

namespace Magento\Sales\Model\Order {

    if (!class_exists(Payment::class)) {
        class Payment
        {
            /** @var string|null */
            private $method;

            public function setMethod(?string $method): self
            {
                $this->method = $method;
                return $this;
            }

            public function getMethod(): ?string
            {
                return $this->method;
            }
        }
    }
}

namespace Magento\Sales\Model {

    /**
     * Deliberately simplified: real Magento\Sales\Model\Order extends AbstractModel/DataObject
     * and resolves getX()/setX() through __call() magic. This stub implements the exact subset
     * SetDefaultTbiStatus actually calls directly, backed by a real data array so behaviour
     * (setStatus/setState/setData persisting, getData reading it back) is genuinely exercised
     * rather than mocked away.
     */
    if (!class_exists(Order::class)) {
        class Order implements \Magento\Sales\Api\Data\OrderInterface
        {
            const STATE_NEW = 'new';
            const STATE_PENDING_PAYMENT = 'pending_payment';
            const STATE_PROCESSING = 'processing';
            const STATE_COMPLETE = 'complete';
            const STATE_CLOSED = 'closed';
            const STATE_CANCELED = 'canceled';
            const STATE_HOLDED = 'holded';
            const STATE_PAYMENT_REVIEW = 'payment_review';

            private $data = [];
            private $status;
            private $state;
            private $payment;

            public function setPayment($payment): self
            {
                $this->payment = $payment;
                return $this;
            }

            public function getPayment()
            {
                return $this->payment;
            }

            public function getData($key = null)
            {
                if ($key === null) {
                    return $this->data;
                }
                return $this->data[$key] ?? null;
            }

            public function setData($key, $value = null): self
            {
                $this->data[$key] = $value;
                return $this;
            }

            public function setStatus($status): self
            {
                $this->status = $status;
                return $this;
            }

            public function getStatus()
            {
                return $this->status;
            }

            public function setState($state): self
            {
                $this->state = $state;
                return $this;
            }

            public function getState()
            {
                return $this->state;
            }

            public function getIncrementId()
            {
                return $this->data['increment_id'] ?? null;
            }

            public function setIncrementId($incrementId): self
            {
                $this->data['increment_id'] = $incrementId;
                return $this;
            }

            public function getId()
            {
                return $this->data['entity_id'] ?? null;
            }
        }
    }
}

namespace Magento\Framework\Setup\Patch {

    if (!interface_exists(PatchInterface::class)) {
        interface PatchInterface
        {
            public function apply();

            public static function getDependencies();

            public function getAliases();
        }
    }

    if (!interface_exists(SchemaPatchInterface::class)) {
        interface SchemaPatchInterface extends PatchInterface
        {
        }
    }

    if (!interface_exists(DataPatchInterface::class)) {
        interface DataPatchInterface extends PatchInterface
        {
        }
    }
}

namespace Magento\Framework\Setup {

    if (!interface_exists(ModuleDataSetupInterface::class)) {
        interface ModuleDataSetupInterface
        {
            public function startSetup();

            public function getConnection();

            public function getTable($tableName, $moduleName = 'default_setup');

            public function endSetup();
        }
    }

    if (!interface_exists(SchemaSetupInterface::class)) {
        interface SchemaSetupInterface
        {
            public function startSetup();

            public function getConnection();

            public function getTable($tableName, $moduleName = 'default_setup');

            public function endSetup();
        }
    }

    if (!interface_exists(ModuleContextInterface::class)) {
        interface ModuleContextInterface
        {
            public function getVersion();
        }
    }

    if (!interface_exists(UninstallInterface::class)) {
        interface UninstallInterface
        {
            public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context);
        }
    }
}

namespace Magento\Payment\Model\Method {

    if (!class_exists(AbstractMethod::class)) {
        abstract class AbstractMethod
        {
            protected $_code;

            public function getCode()
            {
                return $this->_code;
            }

            public function setCode($code): self
            {
                $this->_code = $code;
                return $this;
            }
        }
    }
}

namespace Magento\Quote\Model {

    if (!class_exists(Quote::class)) {
        class Quote
        {
            private $grandTotal = 0.0;
            private $id;
            private $data = [];
            private $billingAddress;
            private $shippingAddress;
            private $payment;
            private $addedProducts = [];

            public function setGrandTotal($grandTotal): self
            {
                $this->grandTotal = $grandTotal;
                return $this;
            }

            public function getGrandTotal(): float
            {
                return $this->grandTotal;
            }

            public function setStore($store): self
            {
                return $this;
            }

            public function setCurrency(): self
            {
                return $this;
            }

            public function save(): self
            {
                if ($this->id === null) {
                    $this->id = random_int(1000, 999999);
                }
                return $this;
            }

            public function getId()
            {
                return $this->id;
            }

            public function setCustomerEmail($email): self
            {
                $this->data['customer_email'] = $email;
                return $this;
            }

            public function setCustomerIsGuest($flag): self
            {
                $this->data['customer_is_guest'] = $flag;
                return $this;
            }

            public function setCustomerFirstname($firstname): self
            {
                $this->data['customer_firstname'] = $firstname;
                return $this;
            }

            public function setCustomerLastname($lastname): self
            {
                $this->data['customer_lastname'] = $lastname;
                return $this;
            }

            public function addProduct($product, $request = null)
            {
                $this->addedProducts[] = ['product' => $product, 'request' => $request];
                return $this;
            }

            public function setBillingAddress($address): self
            {
                $this->billingAddress = $address;
                return $this;
            }

            public function getBillingAddress()
            {
                return $this->billingAddress;
            }

            public function setShippingAddress($address): self
            {
                $this->shippingAddress = $address;
                return $this;
            }

            public function getShippingAddress()
            {
                return $this->shippingAddress;
            }

            public function collectTotals(): self
            {
                return $this;
            }

            public function getPayment(): \Magento\Quote\Model\Quote\Payment
            {
                if ($this->payment === null) {
                    $this->payment = new \Magento\Quote\Model\Quote\Payment();
                }
                return $this->payment;
            }

            public function getData($key = null)
            {
                return $key === null ? $this->data : ($this->data[$key] ?? null);
            }
        }
    }
}

namespace Magento\Checkout\Model {

    if (!class_exists(Session::class)) {
        class Session
        {
            /** @var \Magento\Quote\Model\Quote|null */
            protected $quote;

            public function setQuote($quote): self
            {
                $this->quote = $quote;
                return $this;
            }

            public function getQuote()
            {
                return $this->quote;
            }
        }
    }
}

namespace Magento\Checkout\Model\Session {

    if (!class_exists(Proxy::class)) {
        // Real Magento\Checkout\Model\Session\Proxy is a generated deferred-instantiation
        // wrapper around Session; for our purposes it only needs to expose the same public
        // API surface PaymentMethodVisibility calls (getQuote()).
        class Proxy extends \Magento\Checkout\Model\Session
        {
        }
    }
}

namespace Magento\Framework\App\Helper {

    if (!class_exists(Context::class)) {
        class Context
        {
        }
    }

    if (!class_exists(AbstractHelper::class)) {
        abstract class AbstractHelper
        {
            protected $scopeConfig;

            public function __construct(Context $context)
            {
            }
        }
    }
}

// --- The Gateway.php controller graph (only needed for Controller/Api/GatewayTest) ---

namespace Magento\Framework {

    if (!class_exists(DataObject::class)) {
        class DataObject
        {
            protected $data = [];

            public function __construct(array $data = [])
            {
                $this->data = $data;
            }

            public function setData($key, $value = null): self
            {
                if (is_array($key)) {
                    $this->data = $key;
                } else {
                    $this->data[$key] = $value;
                }
                return $this;
            }

            public function getData($key = null)
            {
                if ($key === null) {
                    return $this->data;
                }
                return $this->data[$key] ?? null;
            }
        }
    }
}

namespace Magento\Framework\App {

    if (!interface_exists(RequestInterface::class)) {
        interface RequestInterface
        {
            public function isPost();

            public function getContent();

            public function getHeader($name);

            public function getClientIp();

            public function getParam($key, $defaultValue = null);
        }
    }

    if (!interface_exists(CsrfAwareActionInterface::class)) {
        interface CsrfAwareActionInterface
        {
            public function createCsrfValidationException(RequestInterface $request): ?\Magento\Framework\App\Request\InvalidRequestException;

            public function validateForCsrf(RequestInterface $request): ?bool;
        }
    }
}

namespace Magento\Framework\App\Request {

    if (!class_exists(InvalidRequestException::class)) {
        class InvalidRequestException extends \Exception
        {
        }
    }
}

namespace Magento\Framework\App\Action {

    if (!class_exists(Context::class)) {
        class Context
        {
            private $request;

            public function __construct($request = null)
            {
                $this->request = $request;
            }

            public function getRequest()
            {
                return $this->request;
            }
        }
    }

    if (!class_exists(Action::class)) {
        class Action
        {
            protected $_request;

            public function __construct(Context $context)
            {
                $this->_request = $context->getRequest();
            }

            protected function getRequest()
            {
                return $this->_request;
            }
        }
    }
}

namespace Magento\Framework\Controller\Result {

    if (!class_exists(Json::class)) {
        class Json
        {
            private $data;

            public function setData($data): self
            {
                $this->data = $data;
                return $this;
            }

            public function getData()
            {
                return $this->data;
            }
        }
    }

    if (!class_exists(JsonFactory::class)) {
        class JsonFactory
        {
            public function create(): Json
            {
                return new Json();
            }
        }
    }
}

namespace Magento\Store\Model {

    if (!class_exists(Store::class)) {
        class Store
        {
        }
    }
}

namespace Magento\Catalog\Api {

    if (!interface_exists(ProductRepositoryInterface::class)) {
        interface ProductRepositoryInterface
        {
            public function getById($productId, $editMode = false, $storeId = null, $forceReload = false);
        }
    }
}

namespace Magento\Customer\Api {

    if (!interface_exists(CustomerRepositoryInterface::class)) {
        interface CustomerRepositoryInterface
        {
            public function getById($customerId);
        }
    }
}

namespace Magento\Quote\Model\Quote {

    if (!class_exists(Address::class)) {
        class Address
        {
            private $data = [];
            private $collectShippingRates = false;
            private $shippingMethod;

            public function addData(array $data): self
            {
                $this->data = array_merge($this->data, $data);
                return $this;
            }

            public function getData($key = null)
            {
                return $key === null ? $this->data : ($this->data[$key] ?? null);
            }

            public function setCollectShippingRates($flag): self
            {
                $this->collectShippingRates = (bool) $flag;
                return $this;
            }

            public function collectShippingRates(): self
            {
                return $this;
            }

            public function setShippingMethod($method): self
            {
                $this->shippingMethod = $method;
                return $this;
            }

            public function getShippingMethod()
            {
                return $this->shippingMethod;
            }
        }
    }

    if (!class_exists(AddressFactory::class)) {
        class AddressFactory
        {
            public function create(): Address
            {
                return new Address();
            }
        }
    }
}

namespace Magento\Quote\Model {

    if (!class_exists(QuoteFactory::class)) {
        class QuoteFactory
        {
            public function create(): Quote
            {
                return new Quote();
            }
        }
    }

    if (!class_exists(QuoteManagement::class)) {
        class QuoteManagement
        {
            public function submit(Quote $quote)
            {
            }
        }
    }
}

namespace Magento\Quote\Model\Quote {

    if (!class_exists(Payment::class)) {
        class Payment
        {
            private $data = [];

            public function importData(array $data): self
            {
                $this->data = $data;
                return $this;
            }

            public function getData($key = null)
            {
                return $key === null ? $this->data : ($this->data[$key] ?? null);
            }
        }
    }
}

namespace Monolog {

    if (!class_exists(Logger::class)) {
        class Logger
        {
            public function __construct($name = 'app', array $handlers = [], array $processors = [])
            {
            }

            public function info($message, array $context = [])
            {
            }

            public function error($message, array $context = [])
            {
            }

            public function warning($message, array $context = [])
            {
            }

            public function debug($message, array $context = [])
            {
            }
        }
    }
}

namespace Magento\Framework {

    // Minimal stand-in for Magento\Framework\Phrase, the object the global __() translation
    // helper returns. Supports the same %1/%2-style placeholder substitution FusionPay's own
    // usages rely on (none currently pass arguments, but this keeps the stub honest).
    if (!class_exists(Phrase::class)) {
        class Phrase
        {
            private $text;
            private $args;

            public function __construct($text, array $args = [])
            {
                $this->text = $text;
                $this->args = $args;
            }

            public function __toString(): string
            {
                $rendered = (string) $this->text;
                foreach ($this->args as $i => $arg) {
                    $rendered = str_replace('%' . ($i + 1), (string) $arg, $rendered);
                }
                return $rendered;
            }

            public function getText()
            {
                return $this->text;
            }

            public function getArguments(): array
            {
                return $this->args;
            }
        }
    }
}

namespace Magento\Framework\HTTP\Client {

    if (!class_exists(Curl::class)) {
        class Curl
        {
            public function post($uri, $params)
            {
            }

            public function setOption($name, $value)
            {
            }

            public function getStatus()
            {
            }

            public function getBody()
            {
            }
        }
    }
}

namespace Magento\Config\Model\ResourceModel {

    if (!class_exists(Config::class)) {
        class Config
        {
            public function saveConfig($path, $value, $scope = 'default', $scopeId = 0)
            {
            }
        }
    }
}

namespace Magento\Framework\App\Cache {

    if (!interface_exists(TypeListInterface::class)) {
        interface TypeListInterface
        {
            public function getTypes();

            public function getTypeLabels();

            public function getInvalidated();

            public function invalidate($typeCode);

            public function cleanType($typeCode);
        }
    }
}

namespace Magento\Framework\App\Cache\Type {

    if (!class_exists(Config::class)) {
        class Config
        {
            const TYPE_IDENTIFIER = 'config';
        }
    }
}

namespace Magento\PageCache\Model\Cache {

    if (!class_exists(Type::class)) {
        class Type
        {
            const TYPE_IDENTIFIER = 'full_page';
        }
    }
}

namespace Magento\Framework\Module {

    if (!class_exists(Manager::class)) {
        class Manager
        {
            public function isEnabled($moduleName)
            {
            }
        }
    }
}

namespace {

    // Global __() translation helper, as provided by Magento\Framework\Translate at runtime.
    if (!function_exists('__')) {
        function __($text, ...$args)
        {
            return new \Magento\Framework\Phrase($text, $args);
        }
    }
}
