# Логическая цепочка: от номера машины до скидки

### 1. Пользователь отправляет номер машины

*   **Файл:** `telegram.php`
*   **Действие:** Это главная точка входа. Скрипт получает сообщение от Telegram, загружает сессию пользователя и определяет его текущее состояние. Так как пользователь уже авторизован, его состояние — `awaiting_car_number`.
*   **Результат:** Скрипт выполняет `require_once "awaiting_car_number.php";`.

### 2. Проверка (валидация) номера машины

*   **Файл:** `awaiting_car_number.php`
*   **Действие:**
    *   Скрипт получает номер машины из сообщения, очищает его (приводит к верхнему регистру, убирает пробелы) и берет `subdomain` и `api_key` из сессии.
    *   Вызывается функция `validateCarNumber()` из файла `validator_api.php`.

### 3. Запрос к API

*   **Файл:** `validator_api.php`
*   **Действие:**
    *   Функция `validateCarNumber()` формирует API-запрос.
    *   Она проверяет, активен ли API-ключ.
    *   Получает `UID` с помощью `getUidByApiKey()`.
    *   Отправляет запрос на эндпоинт `/api/validator/validate`.
    *   **Ключевой момент:** При успешном ответе она также вызывает `getPublicGroupIdByApiKey()` и добавляет `PublicGroupID` в возвращаемый результат.
*   **Результат:** Массив с ответом от API (включая `VehicleInfo` и `PublicGroupID`) возвращается в `awaiting_car_number.php`.

### 4. Обработка результата валидации

*   **Файл:** `awaiting_car_number.php`
*   **Действие:**
    *   **Если машина найдена (`"Present": true`):**
        1.  Номер машины сохраняется в сессию (`current_plate`).
        2.  Пользователю отправляется сообщение с деталями (время заезда, текущая стоимость) с помощью `formatVehicleInfo()` из `messages_UI.php`.
        3.  Если `CurrentFee` больше нуля, скрипт переходит к предложению скидок.
    *   **Если машина не найдена:** Отправляется сообщение "машина не найдена", и пользователю предлагается ввести другой номер. Скрипт завершает работу.

### 5. Отображение кнопок скидок

*   **Файл:** `awaiting_car_number.php`
*   **Действие:**
    *   Вызывается `getDiscountOptions()` из `validator_api.php` для загрузки доступных скидок из файла `discounts.json`.
    *   Вызывается `createDiscountKeyboard()` из `messages_UI.php`, куда передаются опции скидок, язык, детали API и `PublicGroupID` из шага 3.
    *   Эта функция создает клавиатуру со всеми кнопками скидок (включая "НАШ КЛИЕНТ", если нужно).
    *   Пользователю отправляется сообщение "Выберите скидку для [номер машины]" с созданной клавиатурой.
*   **Результат:** Пользователь видит кнопки в чате Telegram. Скрипт завершается (`exit`), ожидая нажатия кнопки.

### 6. Пользователь нажимает кнопку (скидка или смена группы)

*   **Файл:** `telegram.php`
*   **Действие:**
    *   На сервер приходит новый запрос, на этот раз с `callback_query`.
    *   Скрипт определяет, с чего начинается `callback_data`:
        *   **Если `discount|`**: Он разбирает данные, сохраняет `message_id` в сессию и выполняет `require_once "awaiting_discount.php";`.
        *   **Если `changegroup|`**: Он разбирает данные, вызывает `changeVisitorGroup()`, отправляет пользователю ответ и возвращает его в состояние `awaiting_car_number`.
        *   **Если `cancel_discount`**: Он удаляет сообщение с кнопками и возвращает пользователя в состояние `awaiting_car_number`.

### 7. Применение скидки (если была нажата кнопка скидки)

*   **Файл:** `awaiting_discount.php`
*   **Действие:**
    *   Скрипт получает `current_plate`, `subdomain`, `api_key` и детали скидки из сессии и `callback_data`.
    *   Вызывает функцию `applyDiscount()` из `validator_api.php`, которая отправляет запрос на нужный эндпоинт (`discount/time`, `discount/sum` или `discount/tariff`).

### 8. Завершение процесса

*   **Файл:** `awaiting_discount.php`
*   **Действие:**
    *   **Если скидка применена успешно:**
        1.  Вызывается `answerCallbackQuery()` для скрытия "часиков" на кнопке.
        2.  Вызывается `deleteMessage()` для удаления сообщения с кнопками (используя `message_id` из сессии).
        3.  Пользователю отправляется финальное сообщение с подтверждением.
        4.  Состояние пользователя сбрасывается обратно в `awaiting_car_number`.
    *   **Если произошла ошибка:** Пользователь информируется об ошибке.
*   **Результат:** Пользователь возвращается к началу процесса, готовый вводить следующий номер.