HEX
Server: Apache
System: Linux server3230.server-vps.com 5.15.0-46-generic #49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64
User: lzgqnjwu (1002)
PHP: 7.4.33
Disabled: NONE
Upload Files
File: //proc/1124/cwd/frontend/controllers/BotController.18.03.php
<?php

namespace frontend\controllers;

use aki\telegram\types\InputMedia\InputMediaDocument;
use cheatsheet\Time;
use common\models\Bot;
use common\models\BotCommands;
use common\models\BotContactBooks;
use common\models\BotContacts;
use common\models\BotUserAction;
use common\models\Help;
use Yii;
use yii\filters\PageCache;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\web\Response;
use aki\telegram\base\Command;
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
use common\helpers\GoogleSheetHelper;

/**
 * Bot controller с автоматической конвертацией XLSX/XLS → CSV через Spout
 */
class BotController extends Controller
{
    public $enableCsrfValidation = false;

    /**
     * @return string
     * Вход в приложение
     */
    public function actionIndex($id = null)
    {
        // Отладка: логируем приход update
        file_put_contents(Yii::getAlias('@web_path') . '/tg_log.txt', date('Y-m-d H:i:s') . " - id: $id\n", FILE_APPEND);

        if (!$id) {
            return 'ok';
        }

        $bot_data = Bot::find()->where(['id' => $id])->one();
        if (!$bot_data || !$bot_data->token) {
            return 'ok';
        }

        $token = $bot_data->token;
        $user_id = $bot_data->user_id;

        // Инициализируем Telegram
        \Yii::$app->setComponents([
            'telegram' => [
                'class' => \aki\telegram\Telegram::class,
                'botToken' => $token,
            ]
        ]);
        $telegram = Yii::$app->telegram;
        $message_data = $telegram->input->message ?? null;
        if (!$message_data) {
            return 'ok';
        }

        $message_text = $message_data->text ?? null;
        $chat_id = $message_data->chat->id ?? null;

        $mini_path = null;
        $document_id = null;

        if (isset($message_data->document['file_id'])) {
            $document_id = $message_data->document['file_id'];
        } elseif (isset($message_data->photo[2]['file_id'])) {
            $document_id = $message_data->photo[2]['file_id'];
        } elseif (isset($message_data->voice['file_id'])) {
            $document_id = $message_data->voice['file_id'];
            $audio_data = $telegram->getFile(['file_id' => $document_id]);
            $audio_path = $audio_data['result']['file_path'] ?? null;
        }

        if ($document_id) {
            $file_data = $telegram->getFile(['file_id' => $document_id]);
            $file_path = $file_data['result']['file_path'] ?? null;

            if ($file_path) {
                $file_name = basename($file_path);
                $res_file_name = uniqid() . '_' . $file_name;
                $path = Yii::getAlias('@storage/web/source/1/') . $res_file_name;
                $mini_path = '1/' . $res_file_name;

                $file_url = $telegram->getFileUrl(['file_id' => $document_id]);
                if ($file_url) {
                    file_put_contents($path, file_get_contents($file_url));

                    if (isset($message_data->voice['file_id'])) {
                        self::actionuserregistration($chat_id, $id, $user_id, $message_text ?? '', $mini_path);
                    }
                }
            }
        }

        // === ОБРАБОТКА /start команды ===
        try {
            Command::run("/start", function ($telegram, $arr) use ($chat_id, $id, $user_id) {
                self::actionuserregistration($chat_id, $id, $user_id, '/start', '---');
                return true;
            });
        } catch (\Throwable $e) {
            file_put_contents(
                Yii::getAlias('@web_path') . '/tg_error.txt',
                $e->getMessage() . "\n" . $e->getTraceAsString() . "\n",
                FILE_APPEND
            );
        }

        // === ОБРАБОТКА команд /reg и регистрация пользователя ===
        if ($message_text === '/reg') {
            Yii::$app->cache->set('reg_step_' . $chat_id, 'ask_name', 3600);
            $answer_text = BotCommands::find()
                    ->where(['command' => $message_text, 'bot_id' => $id, 'user_id' => $user_id])
                    ->select('message')
                    ->scalar() ?? "👋 Вітаю! Введіть ваше ім’я:";
            $telegram->sendMessage(['chat_id' => $chat_id, 'text' => $answer_text]);
            return true;
        }

        $regStep = Yii::$app->cache->get('reg_step_' . $chat_id);
        if ($regStep) {
            $data = Yii::$app->cache->get('reg_data_' . $chat_id) ?? ['id' => $chat_id];
            $data['id'] = $chat_id;
            switch ($regStep) {
                case 'ask_name':
                    $data['name'] = $message_text;
                    Yii::$app->cache->set('reg_data_' . $chat_id, $data, 3600);
                    Yii::$app->cache->set('reg_step_' . $chat_id, 'ask_company', 3600);
                    $telegram->sendMessage(['chat_id' => $chat_id, 'text' => "🏢 Введіть назву вашої компанії:"]);
                    return true;
                case 'ask_company':
                    $data['company'] = $message_text;
                    Yii::$app->cache->set('reg_data_' . $chat_id, $data, 3600);
                    Yii::$app->cache->set('reg_step_' . $chat_id, 'ask_phone', 3600);
                    $telegram->sendMessage([
                        'chat_id' => $chat_id,
                        'text' => "📞 Натисніть кнопку нижче, щоб поділитися номером:",
                        'reply_markup' => json_encode([
                            'keyboard' => [[['text' => '📲 Поділитися номером', 'request_contact' => true]]],
                            'resize_keyboard' => true,
                            'one_time_keyboard' => true
                        ])
                    ]);
                    return true;
                case 'ask_phone':
                    $data['phone'] = $message_data->contact['phone_number'] ?? 'Не додано';
                    $data['allow'] = 0;
                    // Отправляем в Google Sheets
                    $this->appendToGoogleSheet($data);
                    Yii::$app->cache->delete('reg_step_' . $chat_id);
                    Yii::$app->cache->delete('reg_data_' . $chat_id);
                    $telegram->sendMessage(['chat_id' => $chat_id, 'text' => "✅ Дякуємо, {$data['name']}! Ваші дані збережено. Дочекайтеся підтверждення доступу."]);
                    return true;
            }
        }

        // === ОБРАБОТКА /search режима ===
        $searchCacheKey = 'bot_search_mode_' . $id . '_' . $chat_id;
        $msgLower = mb_strtolower($message_text ?? '', 'UTF-8');

        if ($msgLower === '/search') {
            Yii::$app->cache->set($searchCacheKey, true, 7200);
        }

        $searchCmdAllowed = BotCommands::find()->where(['bot_id' => $id, 'command' => '/search'])->exists();
        $isSearchModeActive = Yii::$app->cache->get($searchCacheKey);

        if ($searchCmdAllowed && $message_text && $message_text[0] !== '/' && $isSearchModeActive) {
            try {
                $results = $this->actionSearchProduct($message_text, $id);
                $this->sendSearchResults($telegram, $chat_id, $results, $token);
                self::actionuserregistration($chat_id, $id, $user_id, $message_text, $mini_path);
                return true;
            } catch (\Throwable $e) {
                Yii::error("SEARCH ERROR: " . $e->getMessage());
                return true;
            }
        }

        // === ОБРАБОТКА любых других команд ===
        if ($message_text) {
            $command_message_data = BotCommands::find()
                ->where(['command' => $message_text, 'bot_id' => $id, 'user_id' => $user_id])
                ->one();
            $answer_text = $command_message_data->message ?? (($message_text === '/start') ? 'Приветствуем Вас' : (str_starts_with($message_text, '/') ? 'Команда не найдена' : null));

            if ($answer_text) {
                $telegram->sendMessage(['chat_id' => $chat_id, 'text' => $answer_text, 'parse_mode' => 'HTML']);
            } elseif ($message_text !== '/start') {
                self::actionuserregistration($chat_id, $id, $user_id, $message_text, $mini_path);
            }
        }
        $mss_photo    = $message_data->photo ?? null;
        $mss_audio    = $message_data->voice ?? null;
        $mss_document = $message_data->document ?? null;
        // === Файлы без текста ===
        if (($mss_document || $mss_photo) && !$message_text) {
            self::actionuserregistration($chat_id, $id, $user_id, $message_text ?? null, $mini_path);
        }

        return 'ok';
    }

    /**
     * @param $telegram
     * @param $chat_id
     * @param $key
     */
    public static function actionuserregistration($chat_id = null, $bot_id = null, $user_id = null, $message_text = null, $message_file = null)
    {
        if ($chat_id && $bot_id && $user_id) {
            //проверяем, есть ли такой пользователь в базе
            $contact_status = BotContacts::find()->where(['bot_id' => $bot_id])->andWhere(['contact' => $chat_id])->one();
            if (!$contact_status) {
                //если пользователя нету - проверяем, есть ли дефолтная книга у пользователя
                $default_book = BotContactBooks::find()
                        ->where(['bot_id' => $bot_id])
                        ->andWhere(['user_id' => $user_id])
                        ->andWhere(['name' => 'Default'])->one() ?? new BotContactBooks();

                $default_book->bot_id = (string)$bot_id;
                $default_book->user_id = (string)$user_id;
                $default_book->name = (string)'Default';
                $default_book->save();

                $book_id = $default_book->id;
                //если есть дефолтная книга пользователей - добавляем пользователя,
                //если нету дефолтной книги для данного бота - создаем и тогда добавляем нашего пользователя

                $bt_cntct = new BotContacts();
                $bt_cntct->bot_contacts_book_id = (string)$book_id;
                $bt_cntct->bot_id = (string)$bot_id;
                $bt_cntct->contact = (string)$chat_id;
                $bt_cntct->name = (string)'User';
                $bt_cntct->other_data = (string)'-';
                $bt_cntct->visible = (string)'1';
                $bt_cntct->save();
            }

            //пишем данные
            $time_now = date("Y-m-d H:i:s");
            if ($message_text || $message_file) {
                $bot_action_data = new BotUserAction();
                $bot_action_data->user_id = (string)$user_id;
                $bot_action_data->message_from = (string)'Пользователь';
                $bot_action_data->bot_id = (string)$bot_id;
                $bot_action_data->chat_id = (string)$chat_id;
                $bot_action_data->message = (string)$message_text;
                $bot_action_data->image = NULL;
                $bot_action_data->file = (string)$message_file;
                $bot_action_data->admin_comment = NULL;
                $bot_action_data->created_at = (string)$time_now;
                $bot_action_data->save();
            }

            //отправляем уведомление в чат админу
            if ($bot_id) {
                //для начала получаем данные по боту - есть ли для бота указан пользователь для получения уведомлений
                //если есть - отправляем данные указанному контакту
                $bot_data = Bot::find()->where(['id' => $bot_id])->one();
                if ($bot_data) {
                    $admin_chat_id = $bot_data->inform_chat_id;
                    $admin_chat_bot_token = $bot_data->token;
                    $admin_chat_bot_name = $bot_data->name;
                    if ($bot_data->bot_type == 1 && $admin_chat_id && $admin_chat_bot_token) {
                        //если есть chat_id для уведомлений + есть токен бота = отправляем уведомление о новом событии в боте
                        \Yii::$app->setComponents(['telegram' => [
                            'class' => \aki\telegram\Telegram::class,
                            'botToken' => $admin_chat_bot_token,
                        ]]);
                        $telegram = Yii::$app->telegram;
                        if ($admin_chat_bot_name) {
                            $admin_chat_bot_name = " - " . $admin_chat_bot_name;
                        } else {
                            $admin_chat_bot_name = " ";
                        }

                        if($admin_chat_bot_name){
                            $msg_upd = $admin_chat_bot_name;
                            //добавляем ссылку на наш чат в панели управления
                            if($bot_action_data->id){

                                $contact_data = BotContacts::find()
                                    ->where(['bot_id' => $bot_id])
                                    ->andWhere(['contact' => $chat_id])
                                    ->one();
                                if($contact_data){
                                    $line_id = $contact_data->id;
                                    if($line_id){
                                        $url = env("FRONTEND_HOST_INFO")."/user/botcontactbooks/viewactions?id=".$line_id;
                                        if($url){
                                            $url_tag = "<a href='".$url."'> Перейти в чат </a>";
                                            $admin_chat_bot_name = $admin_chat_bot_name.$url_tag;
                                        }
                                    }
                                }
                            }
                        }

                        $answear_text = "Новое действие в Вашем боте " . $admin_chat_bot_name." Chat ID - ".$chat_id;

                        try {
                            Yii::$app->telegram->sendMessage([
                                'chat_id' => $admin_chat_id,
                                'text' => $answear_text,
                                'parse_mode' => "HTML"
                            ]);
                        } catch (\Exception $e) {
                            Yii::error('BOT SENDER ERROR (BotController LN 364) - CDRMN ERR - : ' . $e->getMessage());
                            return true;
                        }

                        return true;
                    }
                    return true;
                }
            }

        }
        return true;
    }

    /**
     * Конвертація XLSX/XLS → CSV через Spout (швидко і без проблем з пам'яттю)
     */
    private function convertExcelToCsvSpout($excelPath, $csvPath)
    {
        try {
            Yii::warning("Spout конвертація: $excelPath → $csvPath");

            // Визначаємо тип файлу
            $extension = strtolower(pathinfo($excelPath, PATHINFO_EXTENSION));

            // Створюємо reader
            if ($extension === 'xlsx') {
                $reader = ReaderEntityFactory::createXLSXReader();
            } elseif ($extension === 'xls') {
                $reader = ReaderEntityFactory::createXLSReader();
            } else {
                throw new \Exception('Непідтримуваний формат');
            }

            $reader->open($excelPath);

            // Відкриваємо CSV для запису
            $csvFile = fopen($csvPath, 'w');
            if (!$csvFile) {
                throw new \Exception('Не вдалося створити CSV');
            }

            // Читаємо по рядках (streaming!)
            foreach ($reader->getSheetIterator() as $sheet) {
                foreach ($sheet->getRowIterator() as $row) {
                    $rowData = [];
                    $cells = $row->getCells();

                    foreach ($cells as $cell) {
                        $rowData[] = $cell->getValue();
                    }

                    fputcsv($csvFile, $rowData);
                }

                break; // Читаємо тільки перший лист
            }

            fclose($csvFile);
            $reader->close();

            Yii::warning("Spout конвертація завершена успішно");
            return true;

        } catch (\Exception $e) {
            Yii::error("Spout помилка: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Отримує CSV (автоматично конвертує XLSX/XLS через Spout)
     */
    private function getCsvPath($baseName, $botId)
    {
        // Папка для файлів бота
        $storagePath = Yii::getAlias('@storage/web/source/bot_' . $botId);

        // Якщо папки бота немає - використовуємо загальну папку (для зворотної сумісності)
        if (!is_dir($storagePath)) {
            $storagePath = Yii::getAlias('@storage/web/source');
        }

        $csvPath = $storagePath . '/' . $baseName . '.csv';
        $xlsxPath = $storagePath . '/' . $baseName . '.xlsx';
        $xlsPath = $storagePath . '/' . $baseName . '.xls';

        // Якщо CSV існує - перевіряємо актуальність
        if (file_exists($csvPath)) {
            $csvTime = filemtime($csvPath);

            // Перевіряємо чи XLSX/XLS новіший
            if (file_exists($xlsxPath) && filemtime($xlsxPath) > $csvTime) {
                Yii::warning("XLSX новіший, реконвертація через Spout");
                $this->convertExcelToCsvSpout($xlsxPath, $csvPath);
            } elseif (file_exists($xlsPath) && filemtime($xlsPath) > $csvTime) {
                Yii::warning("XLS новіший, реконвертація через Spout");
                $this->convertExcelToCsvSpout($xlsPath, $csvPath);
            }

            return $csvPath;
        }

        // CSV не існує - конвертуємо XLSX/XLS
        if (file_exists($xlsxPath)) {
            Yii::warning("Конвертуємо XLSX через Spout");
            if ($this->convertExcelToCsvSpout($xlsxPath, $csvPath)) {
                return $csvPath;
            }
        }

        if (file_exists($xlsPath)) {
            Yii::warning("Конвертуємо XLS через Spout");
            if ($this->convertExcelToCsvSpout($xlsPath, $csvPath)) {
                return $csvPath;
            }
        }

        throw new \Exception("Файл $baseName не знайдено для бота $botId");
    }

    public function actionSearchProduct($text, $bot_id)
    {
        $storagePath = Yii::getAlias('@storage/web/source/bot_' . $bot_id);
        $files = glob($storagePath . '/*.csv');
        $text = mb_strtolower(trim($text), 'UTF-8');

        if (empty($files) || mb_strlen($text) < 2) return [];

        $stockData = [];
        $results = [];

        // ШАГ 1. Сначала ищем файл СКЛАДА (Sklad)
        // Загружаем остатки в массив: [Артикул => Кол-во]
        foreach ($files as $filePath) {
            $fileName = basename($filePath);
            // Если в имени файла есть "Sklad" или "Склад"
            if (mb_stripos($fileName, 'sklad') !== false || mb_stripos($fileName, 'склад') !== false) {
                if (($handle = fopen($filePath, 'r')) !== false) {
                    fgetcsv($handle); // Пропускаем заголовок
                    while (($row = fgetcsv($handle)) !== false) {
                        // Sklad: Col 0 = Артикул, Col 2 = Остаток
                        if (isset($row[0])) {
                            $art = trim($row[0]);
                            // Если колонки 2 нет, ставим 0
                            $qty = isset($row[2]) ? trim($row[2]) : '0';
                            $stockData[$art] = $qty;
                        }
                    }
                    fclose($handle);
                }
            }
        }

        // ШАГ 2. Ищем в ПРАЙСЕ и других файлах
        foreach ($files as $filePath) {
            $fileName = basename($filePath);

            // Склад мы уже обработали, его пропускаем
            if (mb_stripos($fileName, 'sklad') !== false || mb_stripos($fileName, 'склад') !== false) continue;

            // Определяем, это ПРАЙС-ЛИСТ или просто левая таблица (tab1)?
            // Считаем прайсом, если в имени есть "Pricelist" или "Прайс"
            $isPricelist = (mb_stripos($fileName, 'pricelist') !== false || mb_stripos($fileName, 'прайс') !== false);

            if (($handle = fopen($filePath, 'r')) !== false) {
                $headers = fgetcsv($handle); // Читаем заголовки

                // Чистим заголовки
                if ($headers) {
                    foreach ($headers as $k => $h) $headers[$k] = trim($h, "\xEF\xBB\xBF \t\n\r\0\x0B");
                }

                while (($row = fgetcsv($handle)) !== false) {
                    // Проверяем совпадение текста во всей строке
                    $rowStr = implode(' ', $row);
                    if (mb_stripos($rowStr, $text, 0, 'UTF-8') !== false) {

                        $item = [];

                        if ($isPricelist) {
                            // === ЛОГИКА ДЛЯ ПРАЙСА (ЖЕСТКИЕ ИНДЕКСЫ) ===
                            // 0-Арт, 1-Назв, 2-Ед, 3-Цена, 4-Упак, 5-Фото

                            $article = isset($row[0]) ? trim($row[0]) : '';

                            $item['type']    = 'product'; // Метка для вывода
                            $item['article'] = $article;
                            $item['name']    = isset($row[1]) ? trim($row[1]) : 'Без назви';
                            $item['unit']    = isset($row[2]) ? trim($row[2]) : '';
                            $item['price']   = isset($row[3]) ? trim($row[3]) : '';
                            $item['packing'] = isset($row[4]) ? trim($row[4]) : '';
                            $item['image']   = isset($row[5]) ? trim($row[5]) : null;

                            // Подтягиваем остаток из Sklad
                            if ($article && isset($stockData[$article])) {
                                $item['stock'] = $stockData[$article];
                            } else {
                                $item['stock'] = '0';
                            }
                        } else {
                            // === ЛОГИКА ДЛЯ ДРУГИХ ФАЙЛОВ (tab1 контакты) ===
                            $item['type'] = 'general';
                            // Берем 6-ю колонку как фото (твое требование)
                            $item['image'] = (isset($row[5]) && filter_var($row[5], FILTER_VALIDATE_URL)) ? $row[5] : null;
                            $item['headers'] = $headers;
                            $item['row'] = $row;
                        }

                        $results[] = $item;
                        if (count($results) >= 10) break 2;
                    }
                }
                fclose($handle);
            }
        }

        return $results;
    }

    private function sendSearchResults($telegram, $chat_id, $results, $bot_token = null)
    {
        if (empty($results)) {
            $telegram->sendMessage([
                'chat_id' => $chat_id,
                'text' => "🔍 Нічого не знайдено.",
                'parse_mode' => "HTML"
            ]);
            return;
        }

        $getEnv = function($key, $default) {
            if (isset($_ENV[$key])) return $_ENV[$key];
            $val = getenv($key);
            if ($val !== false) return $val;
            if (isset($_SERVER[$key])) return $_SERVER[$key];
            return $default;
        };

        $targetToken = $getEnv('TARGET_BOT_TOKEN', '');

        if ($bot_token && $targetToken && trim($bot_token) === trim($targetToken)) {
            $lbl_article = $getEnv('BOT_LABEL_ARTICLE', '🔢 Артикул: ');
            $lbl_price   = $getEnv('BOT_LABEL_PRICE',   '💰 Ціна: ');
            $lbl_unit    = $getEnv('BOT_LABEL_UNIT',    '📏 Одиниця: ');
            $lbl_packing = $getEnv('BOT_LABEL_PACKING', '📦 Норма пакування: ');
            $lbl_stock   = $getEnv('BOT_LABEL_STOCK',   '✅ Доступно: ');
        } else {
            $lbl_article = '🔢 Артикул: ';
            $lbl_price   = '💰 Ціна: ';
            $lbl_unit    = '📏 Одиниця: ';
            $lbl_packing = '📦 Норма пакування: ';
            $lbl_stock   = '✅ Доступно: ';
        }


        foreach ($results as $item) {
            $caption = "";
            $photoUrl = isset($item['image']) ? $item['image'] : null;

            if (isset($item['type']) && $item['type'] === 'product') {
                $caption .= "📦 <b>" . htmlspecialchars($item['name']) . "</b>\n";

                // === ИСПРАВЛЕНИЕ ===
                // Проверяем: если есть 'article' (из CSV) - берем его, если нет - берем 'vendorCode' (из XML)
                $artVal = isset($item['article']) ? $item['article'] : (isset($item['vendorCode']) ? $item['vendorCode'] : '');
                $caption .= $lbl_article . "<code>" . htmlspecialchars($artVal) . "</code>\n";

                // Дальше идет цена и т.д.
                $caption .= $lbl_price . htmlspecialchars($item['price']) . " EUR (без ПДВ)\n";

                if (!empty($item['unit'])) {
                    $caption .= $lbl_unit . htmlspecialchars($item['unit']) . "\n";
                }
                if (!empty($item['packing'])) {
                    $caption .= $lbl_packing . htmlspecialchars($item['packing']) . "\n";
                }

                $stockVal = isset($item['stock']) ? $item['stock'] : (isset($item['available']) ? $item['available'] : '');
                $caption .= $lbl_stock . "<b>" . htmlspecialchars($stockVal) . "</b>";

            } else {
                if (!empty($item['headers']) && !empty($item['row'])) {
                    foreach ($item['headers'] as $i => $h) {
                        $val = isset($item['row'][$i]) ? trim($item['row'][$i]) : '';
                        if ($val === '' || $val === $photoUrl) continue;
                        $caption .= "<b>" . htmlspecialchars($h) . ":</b> " . htmlspecialchars($val) . "\n";
                    }
                }
            }
            if ($photoUrl && filter_var($photoUrl, FILTER_VALIDATE_URL)) {
                try {
                    $telegram->sendPhoto([
                        'chat_id' => $chat_id,
                        'photo' => $photoUrl,
                        'caption' => $caption,
                        'parse_mode' => "HTML"
                    ]);
                } catch (\Exception $e) {
                    $telegram->sendMessage(['chat_id' => $chat_id, 'text' => $caption, 'parse_mode' => "HTML"]);
                }
            } else {
                $telegram->sendMessage(['chat_id' => $chat_id, 'text' => $caption, 'parse_mode' => "HTML"]);
            }
        }
    }


    private function appendToGoogleSheet($userData)
    {
        $client = new \Google_Client();
        $client->setAuthConfig(Yii::getAlias('@common/config/google/service-account.json'));
        $client->addScope(\Google_Service_Sheets::SPREADSHEETS);
        $service = new \Google_Service_Sheets($client);
        $spreadsheetId = env('GOOGLE_SPREADSHEET_ID'); // ID таблицы
        $range = 'Лист1!A1';
        $values = [[$userData['id'], $userData['name'], $userData['phone'], $userData['company'], $userData['allow']]];
        $body = new \Google_Service_Sheets_ValueRange([
            'values' => $values
        ]);
        $params = [
            'valueInputOption' => 'RAW',
            'insertDataOption' => 'INSERT_ROWS'
        ];
        $response = $service->spreadsheets_values->append($spreadsheetId, $range, $body, $params);
        return true;
    }


    public function checkOrCreateUserInSheet($userData)
    {
        $client = new Google_Client();
        $client->setAuthConfig(Yii::getAlias('@common/config/google/service-account.json'));
        $client->setScopes([Google_Service_Sheets::SPREADSHEETS]);
        $service = new Google_Service_Sheets($client);
        $spreadsheetId = env('GOOGLE_SPREADSHEET_ID');
        $range = 'Лист1!A1';

        // 1. Получаем все строки
        $response = $service->spreadsheets_values->get($spreadsheetId, $range);
        $rows = $response->getValues();

        $foundRowIndex = null;
        $flagValue = null;

        if (!empty($rows)) {
            foreach ($rows as $index => $row) {
                if (isset($row[0]) && $row[0] == $userData['id']) {
                    $foundRowIndex = $index;
                    $flagValue = $row[4] ?? null; // колонка E
                    break;
                }
            }
        }

        // 2. Если НЕ найден — создаем запись
        if ($foundRowIndex === null) {
            $values = [
                [$userData['id'], $userData['name'], $userData['company'], $userData['phone'], false]
            ];

            $body = new Google_Service_Sheets_ValueRange([
                'values' => $values
            ]);

            $params = [
                'valueInputOption' => 'USER_ENTERED'
            ];

            $service->spreadsheets_values->append(
                $spreadsheetId,
                'Sheet1!A:E',
                $body,
                $params
            );

            return false;
        }

        // 3. Если найден — проверяем флажок (колонка E)
        // В Google Sheets checkbox возвращает TRUE/FALSE или "TRUE"/"FALSE"
        if ($flagValue === true || $flagValue === 'TRUE') {
            return true;
        }

        return false;
    }
}