<?php
namespace EasyChat\Controller;

use EasyChat\Library\NotificationHealthService;
use EasyChat\Library\CentralGatewayClient;
use EasyChat\Library\WidgetDomainPolicy;
use EasyChat\Library\RequestContext;
use EasyChat\Model\AppSession;
use EasyChat\Model\Setting;
use EasyChat\View\HtmxFragmentRenderer;
use EasyChat\View\NotificationHealthFragments;

class NotificationHealth extends Base {
    protected $layouts = 'layout';

    public function __construct($registry) {
        parent::__construct($registry);
        if (!isset(RequestContext::session()['manager_id'])) {
            header('Location: index.php?route=auth');
            exit;
        }
        if ((RequestContext::session()['manager_role'] ?? '') !== 'admin') {
            header('Location: index.php?route=index');
            exit;
        }
    }

    public function index() {
        $service = new NotificationHealthService($this->registry);
        $snapshot = $service->snapshot();
        $this->vars['title'] = 'Уведомления | EasyChat';
        $this->vars['notification_health'] = $snapshot;
        $this->vars['notification_health_chip'] = $service->chipPayload($snapshot);
        $this->vars['notification_health_pulse'] = (new NotificationHealthFragments())->pulse($snapshot, $this->vars['notification_health_chip']);
        $this->template->view('notification_health');
    }

    public function pulse() {
        $this->releaseSessionLockForReadOnlyJsonResponse();
        $service = new NotificationHealthService($this->registry);
        $snapshot = $service->snapshot();
        $chip = $service->chipPayload($snapshot);

        (new HtmxFragmentRenderer())->sendHtml(
            (new NotificationHealthFragments())->pulse($snapshot, $chip),
            200,
            ['HX-Reswap' => HtmxFragmentRenderer::notificationHealthPulseSwap()]
        );
    }

    public function status() {
        $this->releaseSessionLockForReadOnlyJsonResponse();
        header('Content-Type: application/json; charset=utf-8');
        $service = new NotificationHealthService($this->registry);
        $snapshot = $service->snapshot();
        echo json_encode([
            'success' => true,
            'health' => $snapshot,
            'chip' => $service->chipPayload($snapshot),
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    public function logoutandroid() {
        header('Content-Type: application/json; charset=utf-8');
        $this->requireCsrfTokenJson();

        $model_appsession = new AppSession($this->registry);
        $before = $model_appsession->getTotalSessions();
        $model_appsession->clearAllSessions();

        $service = new NotificationHealthService($this->registry);
        $snapshot = $service->snapshot();

        echo json_encode([
            'success' => true,
            'removed' => (int)$before,
            'health' => $snapshot,
            'chip' => $service->chipPayload($snapshot),
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    





    public function opencabinet() {
        $this->createCabinetClaim('open_cabinet');
    }

    public function recovercabinet() {
        $this->createCabinetClaim('recover_cabinet');
    }

    private function createCabinetClaim($action) {
        header('Content-Type: application/json; charset=utf-8');
        $this->requireCsrfTokenJson();

        $action = $action === 'recover_cabinet' ? 'recover_cabinet' : 'open_cabinet';

        $model_setting = new Setting($this->registry);
        $license = trim((string)$model_setting->get('chat_license', ''));
        $base_url = CentralGatewayClient::normalizeBaseUrl($model_setting->get('chat_central_api', ''));
        $domain = WidgetDomainPolicy::installHost();
        if ($license === '' || $base_url === '' || $domain === '') {
            http_response_code(422);
            echo json_encode(['success' => false, 'error' => 'active_license_required'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            exit;
        }

        $install_id = CentralGatewayClient::ensureInstallId($model_setting);
        $payload = CentralGatewayClient::withBaseDomain($model_setting, [
            'domain' => $domain,
            'action' => $action,
        ]);
        $result = CentralGatewayClient::postJson(
            $base_url,
            '/cabinet/claims',
            CentralGatewayClient::signedBody($license, $install_id, $payload),
            10,
            $this->registry
        );
        $url = is_array($result['json'] ?? null) ? trim((string)($result['json']['claim_url'] ?? '')) : '';
        $parts = $url !== '' ? parse_url($url) : false;
        $safe_claim = $parts
            && strtolower((string)($parts['scheme'] ?? '')) === 'https'
            && strtolower((string)($parts['host'] ?? '')) === 'easychat24.ru'
            && in_array((string)($parts['path'] ?? ''), ['/cabinet/claim', '/cabinet/recover'], true)
            && (string)($parts['path'] ?? '') === ($action === 'recover_cabinet' ? '/cabinet/recover' : '/cabinet/claim')
            && !isset($parts['user'], $parts['pass'], $parts['port'], $parts['query'])
            && preg_match('/^claim=[A-Za-z0-9_-]{43}$/D', (string)($parts['fragment'] ?? '')) === 1;
        if ((int)($result['status'] ?? 0) !== 201 || !$safe_claim) {
            http_response_code(502);
            echo json_encode(['success' => false, 'error' => 'cabinet_claim_unavailable'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            exit;
        }

        echo json_encode(['success' => true, 'url' => $url, 'expires_in' => 600], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    public function logoutAndroidPulse() {
        if (!$this->requirePulsePost()) {
            return;
        }

        $model_appsession = new AppSession($this->registry);
        $before = $model_appsession->getTotalSessions();
        $model_appsession->clearAllSessions();

        $service = new NotificationHealthService($this->registry);
        $snapshot = $service->snapshot();
        $chip = $service->chipPayload($snapshot);
        $message = $before > 0
            ? 'Все Android-устройства выведены. Для новых push оператору нужно снова войти в приложение.'
            : 'Подключенных Android-устройств уже не было.';

        (new HtmxFragmentRenderer())->sendHtml(
            (new NotificationHealthFragments())->pulse($snapshot, $chip, $message, 'success'),
            200,
            [
                'HX-Reswap' => HtmxFragmentRenderer::notificationHealthPulseSwap(),
                'HX-Trigger' => '{"easychat:notification-health-refreshed":true}',
            ]
        );
    }

    private function requirePulsePost() {
        if (RequestContext::method() !== 'POST' || !$this->verifyCsrfToken()) {
            $service = new NotificationHealthService($this->registry);
            $snapshot = $service->snapshot();
            $chip = $service->chipPayload($snapshot);
            $message = RequestContext::method() !== 'POST'
                ? 'Метод запроса не поддерживается. Обновите страницу и повторите действие.'
                : 'Сессия защиты устарела. Обновите страницу и повторите действие.';

            (new HtmxFragmentRenderer())->sendHtml(
                (new NotificationHealthFragments())->pulse($snapshot, $chip, $message, 'error'),
                RequestContext::method() !== 'POST' ? 405 : 403,
                [
                    'HX-Retarget' => '#notification-health-pulse',
                    'HX-Reswap' => HtmxFragmentRenderer::notificationHealthPulseSwap(),
                ]
            );
            return false;
        }

        return true;
    }
}
