<?php

use App\Adapters\OcModelCatalogProductAdapter;
use App\ApplicationFactory;
use Cart\Cart;
use Cart\Currency;
use Cart\Tax;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
use Openguru\OpenCartFramework\OpenCart\Currency as TelecartCurrency;
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
use Openguru\OpenCartFramework\Support\Arr;
use Psr\Log\LoggerInterface;

$sysLibPath = rtrim(DIR_SYSTEM, '/') . '/library/oc_telegram_shop';
$basePath = rtrim(DIR_APPLICATION, '/') . '/..';
if (is_readable($sysLibPath . '/oc_telegram_shop.phar')) {
    require_once "phar://{$sysLibPath}/oc_telegram_shop.phar/vendor/autoload.php";
} elseif (is_dir("$basePath/oc_telegram_shop")) {
    require_once "$basePath/oc_telegram_shop/vendor/autoload.php";
} else {
    throw new RuntimeException('Unable to locate application directory.');
}

/**
 * @property Config $config
 * @property Log $log
 */
class ControllerExtensionTgshopHandle extends Controller
{
    public function __construct($registry)
    {
        parent::__construct($registry);

        $this->load->model('catalog/product');
        $this->load->model('checkout/order');
        $this->load->model('setting/setting');
    }

    public function index(): void
    {
        $this->session->data['language'] = $this->config->get('config_language');

        $json = $this->model_setting_setting->getSetting('module_telecart');
        if (! isset($json['module_telecart_settings'])) {
            $json['module_telecart_settings'] = [];
        }

        $items = Arr::mergeArraysRecursively($json['module_telecart_settings'], [
            'app' => [
                'shop_base_url' => HTTPS_SERVER, // for catalog: HTTPS_SERVER, for admin: HTTPS_CATALOG
                'language_id' => (int)$this->config->get('config_language_id'),
                'oc_timezone' => $this->config->get('config_timezone'),
            ],
            'paths' => [
                'images' => DIR_IMAGE,
            ],
            'logs' => [
                'path' => DIR_LOGS,
            ],
            'database' => [
                'host' => DB_HOSTNAME,
                'database' => DB_DATABASE,
                'username' => DB_USERNAME,
                'password' => DB_PASSWORD,
                'prefix' => DB_PREFIX,
                'port' => (int)DB_PORT,
            ],
            'store' => [
                'oc_store_id' => 0,
                'oc_default_currency' => $this->config->get('config_currency'),
                'oc_config_tax' => filter_var($this->config->get('config_tax'), FILTER_VALIDATE_BOOLEAN),
            ],
            'orders' => [
                'oc_customer_group_id' => (int)$this->config->get('config_customer_group_id'),
            ],
        ]);

        $appDebug = Arr::get($items, 'app.app_debug', false);

        $app = ApplicationFactory::create($items);

        $app->bind(OcModelCatalogProductAdapter::class, function () {
            return new OcModelCatalogProductAdapter($this->model_catalog_product);
        });

        $app->bind(Url::class, fn() => $this->url);
        $app->bind(Currency::class, fn() => new TelecartCurrency($this->registry));
        $app->bind(Tax::class, fn() => $this->tax);
        $app->bind(Cart::class, fn() => $this->cart);
        $app->bind(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
        $app->singleton(Log::class, fn() => $this->log);

        $app
            ->withLogger(fn($app) => $this->createLogger($appDebug))
            ->bootAndHandleRequest();
    }

    /** @noinspection PhpUnused */
    public function ya_metrika(): void
    {
        $json = $this->model_setting_setting->getSetting('module_telecart');
        if (isset($json['module_telecart_settings'])) {
            $yaCounterId = Arr::get($json, 'module_telecart_settings.metrics.yandex_metrika_counter');
            $raw = <<<JS
    (function(m,e,t,r,i,k,a){
        m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
        m[i].l=1*new Date();
        for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
        k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
    })(window, document,'script','https://mc.yandex.ru/metrika/tag.js?id={$yaCounterId}', 'ym');

    ym({$yaCounterId}, 'init', {ssr: true, defer: true, ecommerce:"dataLayer", accurateTrackBounce:true, trackLinks:true});
JS;

            http_response_code(200);
            header('Content-Type: application/javascript');
            header('Access-Control-Allow-Origin: *');
            header('Access-Control-Allow-Methods: GET, POST');
            header('Access-Control-Allow-Headers: Content-Type, Authorization');
            header('Access-Control-Allow-Credentials: true');
            echo $raw;
        } else {
            http_response_code(404);
        }
    }

    private function createLogger(bool $appDebug = false, string $app = 'TeleCart'): LoggerInterface
    {
        $log = new Logger($app, [], [], new DateTimeZone('UTC'));
        $log->pushHandler(
            new RotatingFileHandler(DIR_LOGS . '/telecart.log', 14, $appDebug ? Logger::DEBUG : Logger::INFO),
        );

        return $log;
    }
}
