<?php
namespace EasyChat\Library\Messenger;

use EasyChat\Library\AppClock;








class AvitoAccessIncidentService {
    const INCIDENT_CODE = 'messenger_api_subscription_required';

    private $db;
    private $prefix;
    private $clock;

    public function __construct($registry) {
        $this->db = $registry->get('db');
        $this->prefix = easychat_db_prefix();
        $this->clock = new AppClock($registry);
    }

    public static function isSubscriptionRestriction(array $result): bool {
        return (int)($result['http_code'] ?? 0) === 402;
    }

    public function observeFailure(int $channel_id, int $contact_id, int $chat_id, string $external_chat_id, array $result): bool {
        if ($channel_id <= 0 || !self::isSubscriptionRestriction($result)) {
            return false;
        }

        $scope_hash = hash('sha256', $external_chat_id !== '' ? $external_chat_id : ('local:' . $contact_id . ':' . $chat_id));
        $now = $this->clock->nowSql();
        $table = $this->prefix . 'messenger_provider_incidents';
        $this->db->query(
            "INSERT INTO `{$table}` SET
                `provider` = 'avito',
                `channel_id` = " . (int)$channel_id . ",
                `contact_id` = " . ($contact_id > 0 ? (int)$contact_id : 'NULL') . ",
                `chat_id` = " . ($chat_id > 0 ? (int)$chat_id : 'NULL') . ",
                `incident_code` = '" . self::INCIDENT_CODE . "',
                `scope_hash` = '" . $this->db->escape($scope_hash) . "',
                `status` = 'active',
                `http_code` = 402,
                `first_seen_at` = '" . $this->db->escape($now) . "',
                `last_seen_at` = '" . $this->db->escape($now) . "',
                `resolved_at` = NULL,
                `occurrence_count` = 1
             ON DUPLICATE KEY UPDATE
                `contact_id` = VALUES(`contact_id`),
                `chat_id` = VALUES(`chat_id`),
                `status` = 'active',
                `http_code` = 402,
                `last_seen_at` = VALUES(`last_seen_at`),
                `resolved_at` = NULL,
                `occurrence_count` = `occurrence_count` + 1"
        );
        return true;
    }

    public function observeSuccess(int $channel_id, int $contact_id, int $chat_id, string $external_chat_id): void {
        if ($channel_id <= 0) {
            return;
        }
        $scope_hash = hash('sha256', $external_chat_id !== '' ? $external_chat_id : ('local:' . $contact_id . ':' . $chat_id));
        $now = $this->clock->nowSql();
        $this->db->query(
            "UPDATE `{$this->prefix}messenger_provider_incidents`
             SET `status` = 'resolved', `resolved_at` = '" . $this->db->escape($now) . "'
             WHERE `provider` = 'avito'
               AND `channel_id` = " . (int)$channel_id . "
               AND `incident_code` = '" . self::INCIDENT_CODE . "'
               AND `scope_hash` = '" . $this->db->escape($scope_hash) . "'
               AND `status` = 'active'"
        );
    }

    public function summary(int $limit = 8): array {
        $limit = max(1, min(20, $limit));
        $table = $this->prefix . 'messenger_provider_incidents';
        $count = $this->db->query(
            "SELECT COUNT(*) AS total, MAX(`last_seen_at`) AS last_seen_at
             FROM `{$table}`
             WHERE `provider` = 'avito' AND `incident_code` = '" . self::INCIDENT_CODE . "' AND `status` = 'active'"
        );
        $total = (int)($count->row['total'] ?? 0);
        $items = [];
        if ($total > 0) {
            $rows = $this->db->query(
                "SELECT i.`chat_id`, i.`contact_id`, i.`first_seen_at`, i.`last_seen_at`, i.`occurrence_count`,
                        COALESCE(NULLIF(mc.`display_name`, ''), 'Диалог Avito') AS display_name
                 FROM `{$table}` i
                 LEFT JOIN `{$this->prefix}messenger_contacts` mc ON mc.`contact_id` = i.`contact_id`
                 WHERE i.`provider` = 'avito' AND i.`incident_code` = '" . self::INCIDENT_CODE . "' AND i.`status` = 'active'
                 ORDER BY i.`last_seen_at` DESC, i.`incident_id` DESC
                 LIMIT " . (int)$limit
            );
            foreach ((array)($rows->rows ?? []) as $row) {
                $items[] = [
                    'chat_id' => max(0, (int)($row['chat_id'] ?? 0)),
                    'display_name' => $this->safeName((string)($row['display_name'] ?? '')),
                    'first_seen_at' => (string)($row['first_seen_at'] ?? ''),
                    'last_seen_at' => (string)($row['last_seen_at'] ?? ''),
                    'occurrence_count' => max(1, (int)($row['occurrence_count'] ?? 1)),
                ];
            }
        }

        return [
            'active' => $total > 0,
            'count' => $total,
            'last_seen_at' => (string)($count->row['last_seen_at'] ?? ''),
            'items' => $items,
            'support_message' => $total > 0 ? $this->supportMessage($total, (string)($count->row['last_seen_at'] ?? '')) : '',
        ];
    }

    private function supportMessage(int $count, string $last_seen_at): string {
        return "Здравствуйте. В профиле Avito подключена интеграция EasyChat через официальный Messenger API.\n\n"
            . "При обращении к " . $count . " диалог(ам) API возвращает HTTP 402: доступ к сообщениям ограничен подпиской. "
            . "Последняя ошибка: " . ($last_seen_at !== '' ? $last_seen_at : 'в настоящее время') . ".\n\n"
            . "Проверьте, пожалуйста, что для профиля и категорий объявлений подключён тариф или подписка с Messenger API, и восстановите доступ к этим диалогам.";
    }

    private function safeName(string $value): string {
        $value = trim(strip_tags($value));
        $value = preg_replace('/[\x00-\x1F\x7F]/u', '', $value);
        $value = $value !== '' ? $value : 'Диалог Avito';
        return function_exists('mb_substr') ? mb_substr($value, 0, 96, 'UTF-8') : substr($value, 0, 96);
    }
}
