<?php

declare(strict_types=1);

namespace app\controllers;

use yii;
use yii\web\Controller;
use yii\web\Response;

use app\models\Product;
use app\models\Search;

class SearchController extends Controller
{
    /**
     * @todo Сессию привязать к аккаунту и проверку по нему делать, иначе её можно просто сбрасывать
     */
    public function actionIndex(): array|string
    {
        // Инициализация
        $query = yii::$app->request->post('request') ?? yii::$app->request->get('q');

        if (yii::$app->request->post('type') === 'product' || yii::$app->request->get('type') === 'product') {
            // Поиск по продуктам

            if (yii::$app->request->post('history')) {
                // Запрошена история

                yii::$app->response->format = Response::FORMAT_JSON;

                return [
                    'search_line_window' => $this->renderPartial('/search/panel', ['history' => true]),
                    '_csrf' => yii::$app->request->getCsrfToken()
                ];
            }

            // Инициализация сессии
            $session = yii::$app->session;
            $session->open();

            // Инициализация ответа
            $response = null;

            // Инициализация параметров
            $timer = 0;

            // Период пропуска запросов (в секундах)
            $period = 3;
            $keep_connect = true;
            $sanction = false;
            $sanction_condition = ($session['last_request'] + $period - time()) < $period;
            $sanction_time = 2;
            $query_min = 2;
            $query_max = 20;

            if (isset($session['last_request'])) {
                // Данные о времени последнего запроса не найдены

                if ($sanction && $sanction_condition) {
                    // Наказание за повторный запрос при условии задержки

                    $session['last_request'] += $sanction_time;
                }
            } else {
                // Это первый запрос

                // Инициализация
                $session['last_request'] = time();

                goto first_request;
            }

            keep_connect_wait:

            // Запись времени последнего запроса и вычисление об истечении таймера
            $timer = $session['last_request'] + $period - time();

            if ($timer > 0) {
                // Ожидание перед повторным запросом при условии что старых запросов нет

                yii::$app->response->statusCode = 202;

                $return = [
                    'timer' => $timer,
                    'search_line_window' => $this->renderPartial('/loading'),
                    '_csrf' => yii::$app->request->getCsrfToken()
                ];
            } else {
                // Повторный запрос по истечению ожидания

                // Очистка времени последнего запроса
                unset($session['last_request']);

                first_request:

                if (strlen($query) < $query_min) {
                    // Выход за ограничения длины с недостатком

                    goto skip_query;
                } else if (strlen($query) > $query_max) {
                    // Выход за ограничения длины с превышением

                    goto skip_query;
                }

                // Запись в историю
                Search::write($query);

                $limit = yii::$app->request->isPost ? 10 : 20;

                if ($response = Product::searchByCatn($query, $limit, [])) {
                    // Данные найдены по поиску в полях Каталожного номера

                    // Запись ответа
                    $return = [
                        'search_line_window' => $this->renderPartial('/search/panel', compact('response')),
                        '_csrf' => yii::$app->request->getCsrfToken()
                    ];

                    if ((int) yii::$app->request->post('advanced')) {
                        // Полноценный поиск

                        // Запись ответа
                        $return['main'] = $this->renderPartial('/search/index', compact('response'));
                        $return['search_line_window_hide'] = 1;
                        $return['redirect'] = '/search?type=product&q=' . $query;
                    }
                } else {
                    // Данные не найдены

                    yii::$app->response->statusCode = 404;
                }
            }

            skip_query:

            if (yii::$app->request->isPost) {
                // POST-запрос

                yii::$app->response->format = Response::FORMAT_JSON;

                return $return ?? [
                    'search_line_window' => $this->renderPartial('/search/panel'),
                    '_csrf' => yii::$app->request->getCsrfToken()
                ];
            } else {
                // GET-запрос

                if (empty($return['main']) && $keep_connect && $timer > 0) {
                    // Режим непрерывного соединения

                    // Ожидание
                    sleep($timer);

                    goto keep_connect_wait;
                }

                return $this->render('/search/index', compact('response', 'timer'));
            }
        }

        if (yii::$app->user->isGuest) {
            return $this->render('/search/index', ['error_auth' => true]);
        } else {
            return $this->render('/search/index');
        }
    }
}
