<?php

declare(strict_types=1);

namespace app\controllers;

use yii;
use yii\web\Controller;
use yii\web\Response;
use yii\web\HttpException;
use yii\web\UploadedFile;
use yii\filters\AccessControl;

use app\models\Product;
use app\models\Settings;
use app\models\SupplyEdgeProduct;
use app\models\Supply;
use app\models\Account;
use app\models\Notification;
use app\models\OrderEdgeSupply;

use Exception;

class ProductController extends Controller
{
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => [
                            'index',
                            'analogs'
                        ]
                    ],
                    [
                        'allow' => true,
                        'roles' => ['@'],
                        'actions' => []
                    ],
                    [
                        'allow' => true,
                        'actions' => [
                            'read',
                            'write',
                            'delete',
                            'connect',
                            'disconnect',
                            'edit-title',
                            'edit-catn',
                            'edit-prod',
                            'edit-name',
                            'edit-dscr',
                            'edit-dmns',
                            'edit-wght',
                            'write-image',
                            'delete-image',
                            'write-cover',
                            'write-image',
                            'status'
                        ],
                        'matchCallback' => function ($rule, $action): bool {
                            if (
                                !yii::$app->user->isGuest
                                && (yii::$app->user->identity->type === 'administrator'
                                    || yii::$app->user->identity->type === 'moderator')
                            ) return true;

                            return false;
                        }
                    ],
                    [
                        'allow' => false,
                        'roles' => ['?'],
                        'denyCallback' => [$this, 'accessDenied']
                    ]
                ]
            ]
        ];
    }

    public function accessDenied()
    {
        // Инициализация
        $cookies = yii::$app->response->cookies;

        // Запись cookie с редиректом, который выполнится после авторизации
        $cookies->add(new Cookie([
            'name' => 'redirect',
            'value' => yii::$app->request->pathInfo
        ]));

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

            // Настройка
            Yii::$app->response->format = Response::FORMAT_JSON;

            // Генерация ответа
            Yii::$app->response->content = json_encode([
                'main' => $this->renderPartial('/account/index'),
                'redirect' => yii::$app->request->pathInfo,
                '_csrf' => Yii::$app->request->getCsrfToken()
            ]);
        } else if (Yii::$app->request->isGet) {
            // GET-запрос

            $this->redirect('/authentication');
        }
    }

    public function actionIndex(string $prod, string $catn): array|string|null
    {
        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

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

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

                return [
                    'main' => $this->renderPartial('index', compact('model')),
                    'redirect' => '/product/' . $catn,
                    '_csrf' => yii::$app->request->getCsrfToken()
                ];
            }

            return $this->render('index', compact('model'));
        } else {
            throw new HttpException(404);
        }
    }

    /**
     * Запись товара
     *
     * @param string $catn Артикул
     */
    public function actionWrite(string $catn, string $prod): array|string|null
    {
        // Инициализация буфера ответа
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Переход в конец алгоритма
            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Найден товар

            if (SupplyEdgeProduct::searchByVertex(Supply::searchByCatnAndProd($catn, $prod)->readId(), $product->readId(), filter: ['type' => 'connect'])) {
                // Удалось найти ребро: ПОСТАВКА -> ТОВАР

                // Запись кода ответа
                yii::$app->response->statusCode = 500;

                // Запись в буфер возврата
                $return['alert'] = "Товар и связь с поставкой уже существует: $catn";

                // Переход в конец алгоритма
                goto end;
            } else {
                // Не удалось найти ребро: ПОСТАВКА -> ТОВАР

                if (SupplyEdgeProduct::write(Supply::searchByCatnAndProd($catn, $prod)->readId(), $product->readId(), data: ['type' => 'connect'])) {
                    // Удалось создать ребро: ПОСТАВКА -> ТОВАР

                    $return['alert'] = "Товар уже существовал, связь с поставкой записана: $catn";
                    $return['catn'] = $catn;
                } else {
                    // Не удалось создать ребро: ПОСТАВКА -> ТОВАР

                    // Запись кода ответа
                    yii::$app->response->statusCode = 500;

                    // Запись в буфер возврата
                    $return['alert'] = "Товар уже существует, попытка связать с поставкой не удалась: $catn";
                }
            }
        } else {
            // Не найден товар

            if ($product = Product::writeEmpty($catn)) {
                // Удалось записать товар

                if (SupplyEdgeProduct::write(Supply::collectionName() . "/$catn", $product->readId(), data: ['type' => 'connect'])) {
                    // Удалось создать ребро: ПОСТАВКА -> ТОВАР

                    $return['alert'] = "Товар и связь с поставкой записаны: $catn";
                    $return['catn'] = $catn;
                } else {
                    // Не удалось создать ребро: ПОСТАВКА -> ТОВАР

                    // Запись кода ответа
                    yii::$app->response->statusCode = 500;

                    // Запись в буфер возврата
                    $return['alert'] = "Удалось создать товар, но не удалось связать с поставкой: $catn";
                }
            } else {
                // Не удалось записать товар

                // Запись кода ответа
                yii::$app->response->statusCode = 500;

                // Запись в буфер возврата
                $return['alert'] = "Не удалось записать товар: $catn";
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

            // Запись типа тела ответа
            yii::$app->response->format = Response::FORMAT_JSON;

            return $return;
        }

        // Переадресация на главную страницу
        return $this->redirect("/");
    }

    /**
     * Чтение товаров
     *
     * @param string $type Тип
     * @param int $page Страница
     *
     * @return string|array|null
     */
    public function actionRead(string $type = 'all', int $page = 1): string|array|null
    {
        if (yii::$app->request->isPost) {
            // POST-запрос

            // Инициализация входных параметров
            $amount = yii::$app->request->post('amount') ?? yii::$app->request->get('amount') ?? 20;
            $order = yii::$app->request->post('order') ?? yii::$app->request->get('order') ?? ['DESC'];

            // Инициализация cookie
            $cookies = yii::$app->response->cookies;

            // Инициализация аккаунта
            $account ?? $account = Account::initAccount();

            // Чтение товаров
            $products = Product::read(where: $type === 'all' || $type === 'inactive' ? [] : ['stts' => $type], limit: $amount, page: $page, order: $order);

            // Запись формата ответа
            yii::$app->response->format = Response::FORMAT_JSON;

            return [
                'products' => $this->renderPartial('/product/list', compact('account', 'products', 'amount', 'page')),
                '_csrf' => yii::$app->request->getCsrfToken()
            ];
        }

        return false;
    }

    /**
     * Удаление товара
     *
     * @param string $catn Артикул
     */
    public function actionDelete(string $prod, string $catn): array|string|null
    {
        // Инициализация буфера ответа
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул или производитель

            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Переход в конец алгоритма
            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            if ($product->disconnect()) {
                // Отсоединён от аналогов

                if ($product->delete() > 0) {
                    // Удалён

                    // Запись в буфер возврата
                    $return['alert'] = "Товар удалён: $catn";
                    $return['location'] = '/';
                } else {
                    // Не удалось удалить

                    // Запись кода ответа
                    yii::$app->response->statusCode = 500;

                    // Запись в буфер возврата
                    $return['alert'] = "Не удалось удалить товар: $catn";

                    // Переход в конец алгоритма
                    goto end;
                }
            } else {
                // Не отсоединён от аналогов

                // Запись кода ответа
                yii::$app->response->statusCode = 500;

                // Запись в буфер возврата
                $return['alert'] = "Не удалось отсоединить от аналогов перед удалением: $catn";

                // Переход в конец алгоритма
                goto end;
            }
        } else {
            // Не найден товар

            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Запись в буфер возврата
            $return['alert'] = "Не удалось найти товар: $catn";

            // Переход в конец алгоритма
            goto end;
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if (Product::searchByCatnAndProd($catn, $prod)) {
            // Обрабатываемый товар ещё существует (подразумевается, что произошла ошибка)

            // Возврат на страницу товара
            return $this->redirect("/product/$catn");
        } else {
            // Обрабатываемый товар не существует (подразумевается, что он успешно удалён)

            // Переадресация на главную страницу
            return $this->redirect("/");
        }
    }

    /**
     * Подключение аналога
     *
     * @param string $prod Производитель
     * @param string $catn Артикул
     */
    public function actionConnect(string $prod, string $catn): array|string|null
    {
        // Инициализация буфера ответа
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул или производитель

            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Переход в конец алгоритма
            goto end;
        }

        if ($from = Product::searchByCatnAndProd($catn, $prod)) {
            // Найден товар

            if (($target_catn = yii::$app->request->post('catn') ?? yii::$app->request->get('catn')) &&
                $target_prod = yii::$app->request->post('prod') ?? yii::$app->request->get('prod')) {
                // Инициализирован артикул и производитель товара для связи

                foreach (explode(',', $target_catn, 50) as $analog) {
                    // Перебор аналогов

                    foreach (explode('/', $analog, 50) as $value) {
                        // Перебор аналогов (дополнительная фильтрация)

                        if ($to = Product::searchByCatnAndProd($value, $target_prod)) {
                            // Существуют товары к которым планируется соединение
                        } else {
                            // Не существуют товары к которым планируется соединение

                            // Инициализация товара
                            if ($to = [Product::writeEmpty($value, $target_prod, true)]) {
                                // Удалось записать товар
                            } else {
                                // Не удалось записать товар

                                // Запись кода ответа
                                yii::$app->response->statusCode = 500;

                                // Запись в буфер возврата
                                $return['alert'] = "Не удалось записать новый товар: $value ($target_prod)";

                                // Переход в конец алгоритма
                                goto end;
                            }
                        }

                        // Инициализация количества созданных рёбер
                        $writed = 0;

                        foreach (is_array($to) ? $to : [$to] as $product) {
                            // Перебор товаров для записи связи: ТОВАР -> ТОВАР

                            // Универсализация данных (приведение к объекту)
                            if (is_array($product) && !$product = Product::searchByCatnAndProd($product['catn'], $product['prod'])) continue;

                            // Запись в группу
                            if ($from->connect($product)) $writed++;
                        }
                    }
                }
            }
        } else {
            // Не найден товар

            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Запись в буфер возврата
            $return['alert'] = "Не удалось найти товар: $catn ($prod)";

            // Переход в конец алгоритма
            goto end;
        }

        // Конец алгоритма
        end:

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

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

            // Запись в буфер возврата
            $return['list'] = $this->renderPartial('analogs', [
                'page' => 1,
                'amount' => yii::$app->request->post('amount') ?? yii::$app->request->get('amount') ?? 30,
                'model' => $from
            ]);

            return $return;
        }

        if (Product::searchByCatnAndProd($catn, $prod)) {
            // Старый товар ещё существует (подразумевается, что произошла ошибка)

            // Возврат на страницу товара
            return $this->redirect("/product/$prod/$catn");
        } else {
            // Обрабатываемый товар не существует (подразумевается, что произошла ошибка)

            // Переадресация на главную страницу
            return $this->redirect("/");
        }
    }

    /**
     * Отключение аналога
     *
     * @param string $catn Артикул
     */
    public function actionDisconnect(string $catn, string $prod): array|string|null
    {
        // Инициализация буфера ответа
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул или производитель

            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Переход в конец алгоритма
            goto end;
        }

        if ($target = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

                if ($target->disconnect()) {
                    // Удалено ребро (связь)

                    // Запись в буфер возврата
                    $return['disconnected'] = 1;
                } else {
                    // Не удалено ребро (связь)

                    // Запись кода ответа
                    yii::$app->response->statusCode = 500;

                    // Запись в буфер возврата
                    $return['alert'] = "Не удалось удалить $catn ($prod) из группы";

                    // Переход в конец алгоритма
                    goto end;
                }
        } else {
            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Запись в буфер возврата
            $return['alert'] = "Не удалось найти товар $catn ($prod)";

            // Переход в конец алгоритма
            goto end;
        }

        // Конец алгоритма
        end:

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

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

            return $return;
        }

        if (Product::searchByCatnAndProd($catn, $prod)) {
            // Обрабатываемый товар ещё существует (подразумевается, что произошла ошибка)

            // Возврат на страницу товара
            return $this->redirect("/product/$prod/$catn");
        } else {
            // Обрабатываемый товар не существует (подразумевается, что произошла ошибка)

            // Переадресация на главную страницу
            return $this->redirect("/");
        }
    }

    /**
     * Отключение аналога
     *
     * @param string $catn Артикул
     */
    public function actionAnalogs(string $catn, string $prod, int $page): array|string|null
    {
        // Инициализация буфера ответа
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул или производитель

            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Переход в конец алгоритма
            goto end;
        }

        // Инициализация количества
        $amount = yii::$app->request->post('amount') ?? yii::$app->request->get('amount') ?? 30;

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Генерация списка
            $list = trim($this->renderPartial('analogs', compact('model', 'page', 'amount')));

            if (!empty($list)) $return['list'] = $list;
        } else {
            // Запись кода ответа
            yii::$app->response->statusCode = 500;

            // Запись в буфер возврата
            $return['alert'] = "Не удалось найти товар $catn ($prod) для инициализации аналогов";

            // Переход в конец алгоритма
            goto end;
        }

        // Конец алгоритма
        end:

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

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

            return $return;
        }

        // Переадресация на главную страницу
        return $this->redirect("/");
    }

    public function actionEditTitle(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';

            $model->prod = $text;

            if ($model->save()) {
                // Товар обновлён

                $return['prod'] = $text;
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            return $this->render('index', compact('model'));
        } else {
            return $this->redirect('/');
        }
    }

    public function actionEditCatn(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $text = yii::$app->request->post('text') ?? yii::$app->request->get('text') ?? 'Без названия';

            $model->catn = $text;

            if ($model->save()) {
                // Товар обновлён

                $return['main'] = $this->renderPartial('index', compact('model'));
                $return['redirect'] = "/product/$model->prod/$model->catn";
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if (Product::searchByCatnAndProd($catn, $prod)) {
            // Старый товар ещё существует (подразумевается, что произошла ошибка)

            // Возврат на страницу товара
            return $this->redirect("/product/$prod/$catn");
        } else {
            // Старый товар не существует (подразумевается, что его артикул успешно изменён)

            // Переадресация на новую страницу товара
            return $this->redirect("/product/$model->catn");
        }
    }

    public function actionEditProd(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $text = yii::$app->request->post('text') ?? yii::$app->request->get('text') ?? 'Без названия';

            $model->prod = $text;

            if ($model->save()) {
                // Товар обновлён

                $return['main'] = $this->renderPartial('index', compact('model'));
                $return['redirect'] = "/product/$model->prod/$model->catn";
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if (Product::searchByCatnAndProd($catn, $prod)) {
            // Старый товар ещё существует (подразумевается, что произошла ошибка)

            // Возврат на страницу товара
            return $this->redirect("/product/$prod/$catn");
        } else {
            // Старый товар не существует (подразумевается, что его артикул успешно изменён)

            // Переадресация на новую страницу товара
            return $this->redirect("/product/$model->catn");
        }
    }

    public function actionEditName(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $text = yii::$app->request->post('text') ?? yii::$app->request->get('text') ?? 'Без названия';

            $model->name = $text;

            if ($model->save()) {
                // Товар обновлён

                $return['main'] = $this->renderPartial('index', compact('model'));
                $return['redirect'] = "/product/$model->prod/$model->catn";
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if (Product::searchByCatnAndProd($catn, $prod)) {
            // Старый товар ещё существует (подразумевается, что произошла ошибка)

            // Возврат на страницу товара
            return $this->redirect("/product/$prod/$catn");
        } else {
            // Старый товар не существует (подразумевается, что его артикул успешно изменён)

            // Переадресация на новую страницу товара
            return $this->redirect("/product/$model->catn");
        }
    }

    public function actionEditDscr(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';

            $product->dscr = $text;

            if ($product->save()) {
                // Товар обновлён

                $return['description'] = $text;
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            return $this->render('index', compact('model'));
        } else {
            return $this->redirect('/');
        }
    }

    public function actionEditDmns(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $text = yii::$app->request->post('text') ?? yii::$app->request->get('text') ?? '0';
            $dimension = yii::$app->request->post('dimension') ?? yii::$app->request->get('dimension') ?? 'x';

            $product->dmns = array_merge(
                $product->dmns ?? [],
                [
                    $dimension => $text
                ]
            );

            if ($product->save()) {
                // Товар обновлён

                $return['dimension'] = $text;
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            return $this->render('index', compact('model'));
        } else {
            return $this->redirect('/');
        }
    }

    public function actionEditWght(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $text = yii::$app->request->post('text') ?? yii::$app->request->get('text') ?? '0';

            $product->wght = $text;

            if ($product->save()) {
                // Товар обновлён

                $return['wght'] = $text;
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            return $this->render('index', compact('model'));
        } else {
            return $this->redirect('/');
        }
    }

    public function actionWriteImage(string $prod, string $catn): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];

        if (empty($catn) || empty($prod)) {
            // Не получен артикул

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

            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация
            $product->file_image = UploadedFile::getInstancesByName('images');
            $product->scenario = $product::SCENARIO_IMPORT_IMAGE;

            if ($product->importImages() > 0) {
                // Товар обновлён

                $return['main'] = $this->renderPartial('index', ['model' => $product]);
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            return $this->render('index', compact('model'));
        } else {
            return $this->redirect('/');
        }
    }

    public function actionDeleteImage(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];
        $index = yii::$app->request->post('index') ?? yii::$app->request->get('index');

        if (empty($catn) || !isset($index) || empty($prod)) {
            // Не получены обязательные параметры

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

            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация (буфер нужен из-за кривых сеттеров)
            $buffer = $product->imgs;

            // Удаление
            unset($buffer[$index]);

            // Запись
            $product->imgs = $buffer;

            if ($product->save()) {
                // Товар обновлён

                $return['main'] = $this->renderPartial('index', ['model' => $product]);
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            return $this->render('index', compact('model'));
        } else {
            return $this->redirect('/');
        }
    }

    public function actionWriteCover(string $catn, string $prod): array|string|null
    {
        // Инициализация
        $return = [
            '_csrf' => yii::$app->request->getCsrfToken()
        ];
        $index = yii::$app->request->post('index') ?? yii::$app->request->get('index');

        if (empty($catn) || empty($index) || empty($prod)) {
            // Не получены обязательные параметры

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

            goto end;
        }

        if ($product = Product::searchByCatnAndProd($catn, $prod)) {
            // Товар найден

            // Инициализация (буфер нужен из-за кривых сеттеров)
            $buffer = $product->imgs;

            foreach ($buffer as $image_index => &$image) {
                // Перебор изображений

                if ($image_index === (int) $index) {
                    // Найдено запрашиваемое изображение

                    // Установка обложки
                    $image['covr'] = true;
                } else {
                    $image['covr'] = false;
                }
            }

            // Запись
            $product->imgs = $buffer;

            if ($product->save()) {
                // Товар обновлён

                $return['main'] = $this->renderPartial('index', ['model' => $product]);
            }
        }

        /**
         * Конец алгоритма
         */
        end:

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

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

            return $return;
        }

        if ($model = Product::searchByCatnAndProd($catn, $prod)) {
            return $this->render('index', compact('model'));
        } else {
            return $this->redirect('/');
        }
    }

    /**
     * Изменение статуса
     *
     * @param string $catn Артикул
     */
    public function actionStatus(string $prod, string $catn): array|string|null
    {
        if (yii::$app->request->isPost) {
            // POST-запрос

            // Запись заголовка с форматом ответа
            yii::$app->response->format = Response::FORMAT_JSON;

            // Инициализация буфера ответа
            $return = [
                '_csrf' => yii::$app->request->getCsrfToken()
            ];

            if (empty($catn) || empty($prod)) {
                // Не получен артикул

                // Запись кода ответа
                yii::$app->response->statusCode = 500;

                // Переход в конец алгоритма
                goto end;
            }

            if ($product = Product::searchByCatnAndProd($catn, $prod)) {
                // Найден товар

                // Запись старого статуса
                $old = $product->stts;

                // Запись параметров
                $product->stts = $stts = yii::$app->request->post('stts') ?? 'inactive';

                if ($product->update() > 0) {
                    // Записаны изменения

                    // Запись в журнал
                    $product->journal(data: [
                        'stts' => [
                            'old' => $old,
                            'new' => $stts
                        ]
                    ]);

                    $return['main'] = $this->renderPartial('index', ['model' => $product]);
                } else {
                    // Не записаны изменения

                    // Отправка уведомления
                    Notification::_write("Не удалось изменить статус на $stts у товара $catn ($prod)", type: Notification::TYPE_ERROR);
                }
            } else {
                // Не найден товар

                // Запись кода ответа
                yii::$app->response->statusCode = 500;

                // Отправка уведомления
                Notification::_write("Не удалось найти товар $catn ($prod)", type: Notification::TYPE_ERROR);

                // Переход в конец алгоритма
                goto end;
            }

            // Конец алгоритма
            end:

            return $return;
        }

        return null;
    }
}
