<?php

namespace Tests;

use App\ApplicationFactory;
use Mockery;
use Monolog\Handler\NullHandler;
use Monolog\Logger;
use Openguru\OpenCartFramework\Application;
use Openguru\OpenCartFramework\Container\Container;
use PHPUnit\Framework\TestCase as BaseTestCase;
use Psr\Log\LoggerInterface;
use Tests\Helpers\DatabaseHelpers;

class TestCase extends BaseTestCase
{
    use DatabaseHelpers;

    protected $app;

    protected function setUp(): void
    {
        parent::setUp();

        $this->app = $this->bootstrapApplication();
    }

    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }

    public static function basePath(): string
    {
        return __DIR__;
    }

    public static function fixturesPath(): string
    {
        return static::basePath() . DIRECTORY_SEPARATOR . 'fixtures';
    }

    private function bootstrapApplication(): Application
    {
        $app = ApplicationFactory::create([
            'app' => [
                'app_enabled' => true,
                'app_name' => 'Telecart',
                'app_icon' => null,
                "theme_light" => "light",
                "theme_dark" => "dark",
                "app_debug" => false,
                'shop_base_url' => 'http://localhost', // for catalog: HTTPS_SERVER, for admin: HTTPS_CATALOG
                'language_id' => 10,
            ],

            'telegram' => [
                "bot_token" => "",
                "chat_id" => null,
                "owner_notification_template" => 'owner_notification_template',
                "customer_notification_template" => 'customer_notification_template',
                "mini_app_url" => "",
            ],

            "metrics" => [
                "yandex_metrika_enabled" => false,
                "yandex_metrika_counter" => "",
            ],

            'store' => [
                'enable_store' => true,
                'feature_coupons' => true,
                'feature_vouchers' => true,
                'oc_store_id' => 777,
                'oc_default_currency' => 'RRR',
                'oc_config_tax' => true,
            ],

            'texts' => [
                'text_no_more_products' => 'Это всё по текущему запросу. Попробуйте уточнить фильтры или поиск.',
                'text_empty_cart' => 'Ваша корзина пуста.',
                'text_order_created_success' => 'Ваш заказ успешно оформлен и будет обработан в ближайшее время.'
            ],

            'orders' => [
                'order_default_status_id' => 11,
                'oc_customer_group_id' => 99,
            ],

            'pulse' => [
                'api_key' => '',
                'batch_size' => 50,
                'max_attempts' => 3,
            ],

            'mainpage_blocks' => [
                [
                    'type' => 'products_feed',
                    'title' => '',
                    'description' => '',
                    'is_enabled' => true,
                    'goal_name' => '',
                    'data' => [
                        'max_page_count' => 10,
                    ],
                ],
            ],

            'cache' => [
                'namespace' => 'telecart',
                'default_lifetime' => 60 * 60 * 24,
                'options' => [
                    'db_table' => 'telecart_cache_items',
                ],
            ],

            'logs' => [
                'path' => '/tmp'
            ],

            'database' => [
                'host' => env('DB_HOSTNAME'),
                'database' => env('DB_DATABASE'),
                'username' => env('DB_USERNAME'),
                'password' => env('DB_PASSWORD'),
                'prefix' => env('DB_PREFIX') ?: 'oc_',
                'port' => env('DB_PORT'),
            ],
        ]);


        $app->setLogger($this->getNullLogger());
        $app->boot();

        $this->registerDependenciesForTests($app);

        return $app;
    }

    /**
     * @template T
     * @param class-string<T> $factoryClass
     * @param array $params
     * @return T
     */
    public function factory(string $factoryClass, array $params = [])
    {
        return $this->app->get($factoryClass);
    }

    private function registerDependenciesForTests(Container $container): void
    {
        $url = Mockery::mock('Url');
        $url->shouldReceive('link')->andReturn('http://localhost');

        $container->bind(\Url::class, function () use ($url) {
            return $url;
        });
    }

    protected function getNullLogger(): LoggerInterface
    {
        $logger = new Logger('Telecart_Tests');
        $logger->pushHandler(new NullHandler());

        return $logger;
    }
}
