<?php
namespace EasyChat\Library\Messenger;

use EasyChat\Model\Setting;







class MaxPersonalPresenter {

    private $registry;
    private $heartbeat;
    private $cadence;
    private $settings;

    public function __construct($registry) {
        $this->registry = $registry;
        $this->heartbeat = new MaxCronHeartbeatRepository($registry);
        $this->cadence = new MaxCronCadenceAnalyzer();
        $this->settings = new Setting($registry);
    }

    public function build(array $channel, array $health = [], array $auth_state = []): array {
        if (!$health) {
            $health = (new MaxHealthPresenter($this->registry))->build($channel);
        }
        $channel = is_array($health['channel'] ?? null) ? $health['channel'] : $channel;
        $channel_settings = is_array($health['settings'] ?? null)
            ? $health['settings']
            : $this->decode((string)($channel['settings_json'] ?? ''));
        if (!$auth_state) {
            $auth_state = (new MaxAuthService($this->registry))->authState($channel);
        }

        $heartbeat = $this->heartbeat->snapshot();
        $cron = $this->cadence->analyze(
            is_array($heartbeat['history'] ?? null) ? $heartbeat['history'] : [],
            null,
            is_array($heartbeat['profile'] ?? null) ? $heartbeat['profile'] : []
        );
        $credentials = $this->decode((string)($channel['credentials_json'] ?? ''));
        $session_status = (string)($health['session']['status'] ?? '');
        $has_account = trim((string)($credentials['account_id'] ?? $channel['bot_user_id'] ?? '')) !== ''
            || (string)($auth_state['status'] ?? '') === 'connected';
        $has_session = $session_status === 'ready';
        $connected = $has_account && $has_session;

        if ($connected) {
            $ui_state = 'dashboard';
            $step = 0;
        } elseif (!$cron['confirmed']) {
            $ui_state = 'wizard';
            $step = 1;
        } else {
            $ui_state = 'wizard';
            $step = 2;
        }

        $lease_until = max(0, (int)$this->settings->get('chat_max_logging_until_ts', '0'));
        $profile = MaxAccountProfile::normalize(
            is_array($channel_settings['account_profile'] ?? null)
                ? $channel_settings['account_profile']
                : []
        );
        $enabled = (string)($channel['status'] ?? 'disabled') === 'active';
        $summary = is_array($health['summary'] ?? null) ? $health['summary'] : [];
        try {
            $incident = (new MaxPersonalIncidentService($this->registry))->summary();
        } catch (\Throwable $e) {
            $incident = ['active' => false];
        }

        return [
            'ui_state' => $ui_state,
            'step' => $step,
            'connected' => $connected,
            'enabled' => $enabled,
            'revision' => max(0, (int)($channel_settings['personal_settings_revision'] ?? 0)),
            'account' => $profile,
            'scope' => MaxInboundScope::fromSettings($channel_settings),
            'dedicated_cron_mode' => MaxPollingService::normalizeDedicatedCronMode((string)($channel_settings['dedicated_cron_mode'] ?? '')),
            'cron' => array_merge($cron, $this->cronCopy($cron)),
            'attention' => $this->attention($connected, $enabled, $cron, $summary, $incident),
            'diagnostics' => [
                'active' => $lease_until > time(),
                'until_ts' => $lease_until,
                'remaining_seconds' => max(0, $lease_until - time()),
            ],
            'summary' => $summary,
            'auth' => $auth_state,
        ];
    }

    private function cronCopy(array $cron): array {
        $state = (string)($cron['state'] ?? 'missing');
        $copy = [
            'missing' => ['Нужно добавить задачу', 'Добавьте отдельный MAX Cron и запустите его каждую минуту.'],
            'running' => ['Проверяем первый запуск', 'Дождитесь завершения задачи — EasyChat обновит состояние автоматически.'],
            'observed_once' => ['Первый запуск получен', 'Ждём ещё два запуска по минутному расписанию.'],
            'verifying' => ['Почти готово', 'Получено два запуска. Следующий подтвердит расписание.'],
            'confirmed' => ['MAX Cron работает', 'Три последовательных запуска подтверждены.'],
            'stale' => ['Cron давно не запускался', 'Проверьте расписание и включите задачу в панели хостинга.'],
            'failed' => ['Запуск завершился с ошибкой', 'Откройте журнал задачи в панели хостинга и проверьте команду.'],
            'stalled' => ['Запуск не завершился', 'Проверьте старый процесс и повторите задачу.'],
            'too_frequent' => ['Запуски идут слишком часто', 'Используйте расписание ровно один раз в минуту.'],
            'irregular' => ['Расписание нестабильно', 'Укажите расписание * * * * * и дождитесь трёх запусков.'],
            'limited_hours' => ['Cron работает только часть времени', 'Запуски появляются лишь в отдельные часы. Проверьте расписание * * * * *.'],
            'low_coverage' => ['Cron часто пропускает запуски', 'Наблюдаемая частота ниже одного раза в минуту. Проверьте расписание * * * * *.'],
        ];
        $selected = $copy[$state] ?? $copy['missing'];
        if ($state === 'irregular' && (string)($cron['diagnosis'] ?? '') === 'fixed_interval') {
            $minutes = max(2, (int)round(max(0, (int)($cron['observed_interval_seconds'] ?? 0)) / 60));
            $selected = [
                'Cron запускается слишком редко',
                'Похоже, задача запускается каждые ' . $minutes . ' мин. Укажите расписание * * * * *.',
            ];
        }
        return [
            'title' => $selected[0],
            'detail' => $selected[1],
        ];
    }

    private function attention(bool $connected, bool $enabled, array $cron, array $summary, array $incident): array {
         
         
         
         
        $incident_action = (string)($incident['action'] ?? '');
        if ($enabled && !empty($incident['active']) && !($connected && $incident_action === 'reconnect')) {
            return array_merge($incident, ['visible' => true, 'source' => 'incident']);
        }
        if (!$connected || !$enabled) {
            return ['visible' => false, 'level' => 'warning', 'title' => '', 'detail' => ''];
        }
        if (!empty($cron['requires_attention'])) {
            $copy = $this->cronCopy($cron);
            return [
                'visible' => true,
                'level' => (string)($cron['severity'] ?? 'warning') === 'error' ? 'error' : 'warning',
                'title' => (string)$copy['title'],
                'detail' => (string)$copy['detail'],
                'source' => 'cron',
            ];
        }
        $summary_code = (string)($summary['code'] ?? 'ok');
        if (!in_array($summary_code, ['warning', 'error'], true)) {
            return ['visible' => false, 'level' => 'warning', 'title' => '', 'detail' => ''];
        }
        return [
            'visible' => true,
            'level' => $summary_code,
            'title' => (string)($summary['title'] ?? 'Личный MAX требует внимания'),
            'detail' => (string)($summary['detail'] ?? 'Откройте диагностику личного MAX.'),
            'source' => 'health',
        ];
    }

    private function decode(string $json): array {
        $decoded = json_decode($json, true);
        return is_array($decoded) ? $decoded : [];
    }
}
