<?php
namespace EasyChat\Library;

use EasyChat\Model\AppSession;
use EasyChat\Model\Setting;

class NotificationHealthService {
    private $registry;

    public function __construct($registry) {
        $this->registry = $registry;
    }

    public function snapshot() {
        $model_setting = new Setting($this->registry);
        $model_appsession = new AppSession($this->registry);

        $empty = $this->emptySnapshot();
        $empty['local_android'] = $this->localAndroidSummary($model_appsession);

        $central_api = CentralGatewayClient::normalizeBaseUrl($model_setting->get('chat_central_api'));
        if ($central_api === '') {
            $empty['error'] = 'central_api_empty';
            return $empty;
        }

        try {
            $body = CentralGatewayClient::buildSignedInstallBody($model_setting, $this->publicDomain());
            $result = CentralGatewayClient::postJson($central_api, '/api/v1/auth/domain-status', $body, 5, $this->registry);
            $status = (int)($result['status'] ?? 0);
            if ($status !== 200 && $status !== 403) {
                $empty['error'] = (string)($result['error_code'] ?: 'gateway_unavailable');
                return $empty;
            }

            $json = is_array($result['json'] ?? null) ? $result['json'] : [];
            return $this->normalizeGatewayPayload($json, $empty);
        } catch (\Throwable $e) {
            $empty['error'] = 'gateway_unavailable';
            return $empty;
        }
    }

    public function chipPayload(array $snapshot) {
        $state = (string)($snapshot['state'] ?? 'gateway_unavailable');
        $mode = (string)($snapshot['mode'] ?? '');
        $remaining = (int)($snapshot['limit']['remaining'] ?? 0);

        $label = '—';
        if ($mode === 'licensed' || $state === 'licensed') {
            $label = '∞';
        } elseif (!empty($snapshot['available'])) {
            $label = (string)$remaining;
        }

        return [
            'available' => !empty($snapshot['available']),
            'state' => $state,
            'mode' => $mode,
            'label' => $label,
            'remaining' => $remaining,
            'purchase_url' => (string)($snapshot['purchase_url'] ?? ''),
            'should_show_critical_modal' => in_array($state, ['warning', 'critical', 'blocked'], true),
        ];
    }

    private function emptySnapshot() {
        return [
            'available' => false,
            'error' => '',
            'state' => 'gateway_unavailable',
            'mode' => '',
            'blocked_reason' => '',
            'limit' => [
                'used' => 0,
                'limit' => 300,
                'remaining' => 0,
                'remaining_percent' => 0,
            ],
            'usage' => [
                'window_days' => 7,
                'last_7_days' => 0,
                'avg_daily' => 0,
                'forecast_days' => null,
                'forecast_date' => '',
                'last_push_at' => '',
            ],
            'channels' => [
                'operator' => [
                    'fcm' => ['active' => 0, 'inactive' => 0],
                    'webpush' => ['active' => 0, 'inactive' => 0],
                ],
                'customer' => [
                    'webpush' => ['active' => 0, 'inactive' => 0],
                ],
                'last_registered_at' => '',
                'last_success_at' => '',
                'last_error_at' => '',
                'last_error_code' => '',
            ],
            'purchase_url' => 'https://easychat24.ru/pricing/',
            'local_android' => [
                'total' => 0,
                'stale_sync' => 0,
                'push_error' => 0,
                'last_error' => '',
                'last_error_at' => '',
            ],
        ];
    }

    private function normalizeGatewayPayload(array $json, array $fallback) {
        $snapshot = $fallback;
        $snapshot['available'] = true;
        $snapshot['error'] = '';

        $health = is_array($json['notification_health'] ?? null) ? $json['notification_health'] : [];
        if ($health) {
            $snapshot['state'] = (string)($health['state'] ?? 'normal');
            $snapshot['mode'] = (string)($health['mode'] ?? ($json['mode'] ?? ''));
            $snapshot['blocked_reason'] = (string)($health['blocked_reason'] ?? ($json['reason'] ?? ''));
            $snapshot['limit'] = array_merge($snapshot['limit'], is_array($health['limit'] ?? null) ? $health['limit'] : []);
            $snapshot['usage'] = array_merge($snapshot['usage'], is_array($health['usage'] ?? null) ? $health['usage'] : []);
            $snapshot['channels'] = array_merge($snapshot['channels'], is_array($health['channels'] ?? null) ? $health['channels'] : []);
            $snapshot['purchase_url'] = (string)($health['purchase_url'] ?? ($json['purchase_url'] ?? $snapshot['purchase_url']));
            return $snapshot;
        }

        $used = (int)($json['trial_push_used'] ?? 0);
        $limit = (int)($json['trial_push_limit'] ?? 300);
        $remaining = max(0, $limit - $used);
        $mode = (string)($json['mode'] ?? '');
        $trialExpired = !empty($json['trial_expired']) || (string)($json['code'] ?? '') === 'trial_limit_exceeded';
        $state = $mode === 'licensed' ? 'licensed' : 'normal';
        if ($trialExpired || $remaining <= 0) {
            $state = 'blocked';
        } elseif ($limit > 0 && ($remaining / $limit) <= 0.1) {
            $state = 'warning';
        } elseif ($limit > 0 && ($remaining / $limit) <= 0.3) {
            $state = 'attention';
        }

        $summary = is_array($json['push_summary'] ?? null) ? $json['push_summary'] : [];
        $snapshot['state'] = $state;
        $snapshot['mode'] = $mode;
        $snapshot['blocked_reason'] = (string)($json['reason'] ?? '');
        $snapshot['limit'] = [
            'used' => $used,
            'limit' => $limit,
            'remaining' => $remaining,
            'remaining_percent' => $limit > 0 ? round(($remaining / $limit) * 100, 1) : 0,
        ];
        $snapshot['channels'] = array_merge($snapshot['channels'], $summary);
        $snapshot['purchase_url'] = (string)($json['purchase_url'] ?? $snapshot['purchase_url']);
        return $snapshot;
    }

    private function localAndroidSummary(AppSession $model_appsession) {
        $summary = $model_appsession->getSessionHealthSummary();
        return [
            'total' => (int)($summary['total'] ?? 0),
            'stale_sync' => (int)($summary['stale_sync'] ?? 0),
            'push_error' => (int)($summary['push_error'] ?? 0),
            'last_error' => (string)($summary['last_error'] ?? ''),
            'last_error_at' => (string)($summary['last_error_at'] ?? ''),
        ];
    }

    private function publicDomain() {
        $host = RequestContext::server()['HTTP_HOST'] ?? '';
        if ($host !== '' && function_exists('easychat_public_host')) {
            $host = easychat_public_host($host);
        }
        return strtolower(trim((string)$host));
    }
}
