<?php

namespace Core\App\Controllers;

use Core\App\Models\Settings;
use Core\System\Response;
use Core\System\Csrf;
use Core\System\Version;
use Core\System\License\LicenseClient;
use Core\System\License\LicenseStorage;
use Core\System\License\Fingerprint;
use Core\System\License\ViolationsReporter;

class UpdatesLicenseController
{
    public function index()
    {
        $settingsModel = new Settings();
        $rows = $settingsModel->getAll();

        $licenseKey = trim((string)($rows['license_key'] ?? ''));

        $cache = LicenseStorage::getCache();
        if (!is_array($cache)) {
            $cache = [];
        }

        $domain = $_SERVER['HTTP_HOST'] ?? '';
        $fingerprint = '';
        try {
            $fingerprint = Fingerprint::generate();
        } catch (\Throwable $e) {
            $fingerprint = '';
        }

        $currentVersion = class_exists(Version::class) ? Version::current() : (defined('MTE_VERSION') ? (string)MTE_VERSION : '1.0.0');
        $product = trim((string)($cache['product'] ?? ''));
        if ($product === '') {
            $product = class_exists(Version::class) ? Version::product() : 'MTEngine';
        }

        $latestVersion = null;
        $updateAvailable = false;
        $updateTitle = null;
        $updateNotes = null;
        $updateDownloadUrl = null;
        $updateMessage = null;
        $updatesStatus = 'not_configured';

        if ($licenseKey !== '') {
            $client = new LicenseClient();
            $updatesRes = $client->checkUpdates($product, $currentVersion, $licenseKey);

            if (is_array($updatesRes) && $updatesRes !== []) {
                $updatesStatus = (string)($updatesRes['status'] ?? 'error');
                $latestVersion = $updatesRes['latest_version'] ?? null;
                $updateAvailable = !empty($updatesRes['update_available']);
                $updateTitle = $updatesRes['title'] ?? null;
                $updateNotes = $updatesRes['notes'] ?? null;
                $updateDownloadUrl = $updatesRes['download_url'] ?? null;
                $updateMessage = $updatesRes['message'] ?? null;
            }
        }

        extract([
            'licenseKey'        => $licenseKey,
            'cache'             => $cache,
            'domain'            => $domain,
            'fingerprint'       => $fingerprint,
            'currentVersion'    => $currentVersion,
            'product'           => $product,
            'latestVersion'     => $latestVersion,
            'updateAvailable'   => $updateAvailable,
            'updateTitle'       => $updateTitle,
            'updateNotes'       => $updateNotes,
            'updateDownloadUrl' => $updateDownloadUrl,
            'updateMessage'     => $updateMessage,
            'updatesStatus'     => $updatesStatus,
        ]);

        require ROOT_PATH . '/admin/templates/header.php';
        require ROOT_PATH . '/admin/templates/updates_license.php';
        require ROOT_PATH . '/admin/templates/footer.php';
    }

    public function verifyNow()
    {
        Csrf::check();

        $settingsModel = new Settings();
        $rows = $settingsModel->getAll();
        $licenseKey = trim((string)($rows['license_key'] ?? ''));

        if ($licenseKey === '') {
            (new ViolationsReporter())->report('admin_missing_key_verify');
            Response::redirect('/admin/updates-license?err=missing_key');
        }

        $client = new LicenseClient();
        $res = $client->verify($licenseKey);

        if (!is_array($res) || empty($res['status'])) {
            (new ViolationsReporter())->report('admin_server_unreachable_verify');
            Response::redirect('/admin/updates-license?err=server_unreachable');
        }

        if (($res['status'] ?? '') !== 'active' || ($res['action'] ?? '') === 'block') {
            (new ViolationsReporter())->report('admin_blocked_verify');
            Response::redirect('/admin/updates-license?err=blocked');
        }

        LicenseStorage::save([
            'license_key'   => $licenseKey,
            'status'        => 'active',
            'action'        => 'allow',
            'type'          => $res['type'] ?? null,
            'type_original' => $res['type_original'] ?? null,
            'expires'       => $res['expires'] ?? null,
            'domain_bound'  => $res['domain_bound'] ?? null,
            'max_domains'   => (int)($res['max_domains'] ?? 0),
            'domains_used'  => (int)($res['domains_used'] ?? 0),
            'product'       => $res['product'] ?? null,
            'plugin_slug'   => $res['plugin_slug'] ?? null,
            'checked_at'    => time(),
            'last_ok_at'    => time(),
            'ttl'           => 3600,
            'failures'      => 0,
        ]);

        Response::redirect('/admin/updates-license?saved=verify_ok');
    }

    public function pingNow()
    {
        Csrf::check();

        $settingsModel = new Settings();
        $rows = $settingsModel->getAll();
        $licenseKey = trim((string)($rows['license_key'] ?? ''));

        if ($licenseKey === '') {
            (new ViolationsReporter())->report('admin_missing_key_ping');
            Response::redirect('/admin/updates-license?err=missing_key');
        }

        $domain = $_SERVER['HTTP_HOST'] ?? '';
        $fp = Fingerprint::generate();

        $client = new LicenseClient();
        $res = $client->ping($licenseKey, $domain, $fp);

        if (!is_array($res) || empty($res['action'])) {
            (new ViolationsReporter())->report('admin_ping_failed');
            Response::redirect('/admin/updates-license?err=ping_failed');
        }

        if (($res['action'] ?? '') === 'block') {
            (new ViolationsReporter())->report('admin_blocked_ping');
            try { LicenseStorage::clear(); } catch (\Throwable $e) {}
            Response::redirect('/admin/updates-license?err=blocked');
        }

        $cache = LicenseStorage::getCache();
        if (!is_array($cache)) $cache = [];
        $cache['ping_at'] = time();
        $cache['ping_last_ok_at'] = time();
        if (!empty($res['product'])) {
            $cache['product'] = $res['product'];
        }
        if (array_key_exists('plugin_slug', $res)) {
            $cache['plugin_slug'] = $res['plugin_slug'];
        }
        LicenseStorage::storeCache($cache);

        Response::redirect('/admin/updates-license?saved=ping_ok');
    }

    public function changeKey()
    {
        Csrf::check();

        $newKey = trim((string)($_POST['license_key'] ?? ''));

        if ($newKey === '') {
            (new ViolationsReporter())->report('admin_missing_key_change');
            Response::redirect('/admin/updates-license?err=missing_key');
        }

        $client = new LicenseClient();
        $res = $client->verify($newKey);

        if (!is_array($res) || empty($res['status'])) {
            (new ViolationsReporter())->report('admin_server_unreachable_change');
            Response::redirect('/admin/updates-license?err=server_unreachable');
        }

        if (($res['status'] ?? '') !== 'active' || ($res['action'] ?? '') === 'block') {
            (new ViolationsReporter())->report('admin_invalid_key_change');
            Response::redirect('/admin/updates-license?err=invalid_key');
        }

        $settingsModel = new Settings();
        $settingsModel->set('license_key', $newKey);

        LicenseStorage::save([
            'license_key'   => $newKey,
            'status'        => 'active',
            'action'        => 'allow',
            'type'          => $res['type'] ?? null,
            'type_original' => $res['type_original'] ?? null,
            'expires'       => $res['expires'] ?? null,
            'domain_bound'  => $res['domain_bound'] ?? null,
            'max_domains'   => (int)($res['max_domains'] ?? 0),
            'domains_used'  => (int)($res['domains_used'] ?? 0),
            'product'       => $res['product'] ?? null,
            'plugin_slug'   => $res['plugin_slug'] ?? null,
            'checked_at'    => time(),
            'last_ok_at'    => time(),
            'ttl'           => 3600,
            'failures'      => 0,
        ]);

        Response::redirect('/admin/updates-license?saved=license_changed');
    }
}
