<?php
namespace Opencart\Catalog\Controller\Extension\Alsendo;

class EcoletAuth extends \Opencart\System\Engine\Controller {
    public function index(): void
    {
        $code = $this->request->get['code'] ?? '';
        $state = $this->request->get['state'] ?? '';
        $baseUrl = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
        if (empty($code) || empty($state)) {
            $this->response->redirect($baseUrl);
            return;
        }
        $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "setting` WHERE `code` = 'alsendo' AND `key` = 'ro_client_secret'");
        if (!$query->num_rows) {
            $this->response->redirect($baseUrl);
            return;
        }
        $secret = $query->row['value'];
        $hash = md5(substr($secret, 0, 10));
        if ($hash !== $state) {
            $this->response->redirect($baseUrl);
            return;
        }
        $clientIdQuery = $this->db->query("SELECT * FROM `" . DB_PREFIX . "setting` WHERE `code` = 'alsendo' AND `key` = 'ro_client_id'");
        if (!$clientIdQuery->num_rows) {
            $this->response->redirect($baseUrl);
            return;
        }
        $clientId = $clientIdQuery->row['value'];
        $redirectUri = $baseUrl . '/index.php?route=extension/alsendo/ecolet_auth';
        if (str_contains($baseUrl, 'localhost') || str_contains($baseUrl, '127.0.0.1')) {
            $redirectUri = 'https://google.com';
        }
        $roSandboxQuery = $this->db->query("SELECT * FROM `" . DB_PREFIX . "setting` WHERE `code` = 'alsendo' AND `key` = 'ro_sandbox'");
        $test = $roSandboxQuery->num_rows && $roSandboxQuery->row['value'] === '1';
        require_once(DIR_EXTENSION . 'alsendo/wrapper/vendor/autoload.php');
        $oauthConfig = [
            'client_id' => $clientId,
            'client_secret' => $secret,
            'redirect_uri' => $redirectUri,
        ];
        $client = new \Alsendo\AlsendoWrapper\Api\Ecolet\EcoletOAuthClient($oauthConfig, $test);
        $this->upsertSetting('ro_client_oauth_code', $code);
        try {
            $token = $client->getAccessToken($code);
        } catch (\Throwable $e) {
            $this->response->redirect($baseUrl);
            return;
        }
        if (!$token) {
            $this->response->redirect($baseUrl);
            return;
        }
        $this->upsertSetting('ro_client_oauth_access_token', $token->getAccessToken());
        $this->upsertSetting('ro_client_oauth_refresh_token', $token->refreshToken);
        $this->upsertSetting('ro_client_oauth_expires_at', (string) $token->expiresAt);
        $this->response->redirect($baseUrl);
    }

    private function upsertSetting(string $key, string $value): void
    {
        $escapedKey = $this->db->escape($key);
        $escapedValue = $this->db->escape($value);
        $query = $this->db->query("SELECT setting_id FROM `" . DB_PREFIX . "setting` WHERE `code` = 'alsendo' AND `key` = '" . $escapedKey . "' LIMIT 1");
        if ($query->num_rows) {
            $this->db->query("UPDATE `" . DB_PREFIX . "setting` SET `value` = '" . $escapedValue . "' WHERE `code` = 'alsendo' AND `key` = '" . $escapedKey . "'");
        } else {
            $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` (`store_id`, `code`, `key`, `value`, `serialized`) VALUES (0, 'alsendo', '" . $escapedKey . "', '" . $escapedValue . "', 0)");
        }
    }
}
