<?php

declare(strict_types=1);

namespace app\controllers;

use app\models\Account;
use yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\web\Cookie;

use app\models\Product;
use app\models\Order;
use app\models\OrderEdgeSupply;
use app\models\Notification;

use Exception;

class CartController extends Controller
{
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                        'actions' => [
                            'index',
                            'edit-comm',
                            'count'
                        ]
                    ],
                    [
                        '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' => '/cart',
                '_csrf' => yii::$app->request->getCsrfToken()
            ]);
        } else if (yii::$app->request->isGet) {
            // GET-запрос

            $this->redirect('/authentication');
        }
    }
    /**
     * Страница: "Корзина"
     *
     * @see $this->behaviors Доступ только аутентифицированным
     */
    public function actionIndex(): string|array|null|Response
    {
        // Инициализация
        $page = yii::$app->request->get('page') ?? yii::$app->request->post('page') ?? 1;
        $account = Account::initAccount();

        // Поиск корзины (текущего заказа)
        $data = Order::searchSmart()[0] ?? null;

        if (empty($data['order'])) {
            // Корзина не инициализирована

            // Инициализация
            $data['order'] = new Order();

            if ($data['order']->save()) {
                // Удалось инициализировать заказ

                // Подключение заказа к аккаунту
                $data['order']->connect($account);
            } else {
                throw new Exception('Не удалось инициализировать заказ');
            }
        }

        // Инициализация содержимого корзины
        $data['supplies'] = $data['order']->supplies(10, $page);

        // Инициализация данных списка для выбора терминала
        $delivery_to_terminal_list = $account->genListTerminalsTo();
        $array_unshift_in_start = function (array &$array, string|int $key, mixed $value) {
            $array = array_reverse($array, true);
            $array[$key] = $value;
            return $array = array_reverse($array, true);
        };
        $array_write_default_value = function (array &$array, string $key = 'Выберите', string $value = 'Выберите') use ($array_unshift_in_start) {
            if (isset($array[$key])) {
                // Смещение или ассоциация найдена

                // Деинициализация
                unset($array[$key]);

                // Инициализация
                $array_unshift_in_start($array, $key, $value);
            }
        };

        // Сортировка по алфавиту
        asort($delivery_to_terminal_list);

        // Перемещение в начало массива значения "Выберите"
        $array_write_default_value($delivery_to_terminal_list);

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

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

            return [
                'main' => $this->renderPartial('index', compact('account', 'data', 'delivery_to_terminal_list')),
                'title' => 'Корзина',
                'redirect' => '/cart',
                '_csrf' => yii::$app->request->getCsrfToken()
            ];
        }

        return $this->render('index', compact('account', 'data', 'delivery_to_terminal_list'));
    }

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

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

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

            goto end;
        }

        if ($edges = OrderEdgeSupply::searchBySupplyCatnAndProd($catn, $prod, Order::searchByType()[0]['order'])) {
            // Рёбра найдены (связи заказа с поставкой)

            // Инициализация
            $amount = 0;

            foreach ($edges as $edge) {
                // Перебор рёбер (связей заказа с поставкой)

                // Инициализация
                $text = yii::$app->request->post('text') ?? yii::$app->request->get('text') ?? 'Комментарий к заказу';

                $comm = $edge->comm ?? null;
                $edge->comm = empty($text) ? 'Комментарий к заказу' : $text;

                if ($edge->save()) {
                    // Ребро обновлено

                    // Запись в журнал
                    $edge->journal('update', ['comm' => ['from' => $comm, 'to' => $edge->comm]]);

                    // Обновление счётчика
                    ++$amount;

                    // Запись в буфер ответа
                    $return['comm'] = $edge->comm;
                }
            }

            if ($amount > 0) {
                // Удалось записать минимум 1 связь с поставкой

                Notification::_write("Обновлён комментарий к товару $catn ($amount шт)");
            } else {
                // Не удалось записать минимум 1 связь с поставкой

                Notification::_write("Не удалось обновить комментарий к товару $catn");
            }
        }

        /**
         * Конец алгоритма
         */
        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 actionCount(): array|string|null
    {
        if (yii::$app->request->isPost) {
            // POST-запрос

            // Настройка типа ответа
            yii::$app->response->format = Response::FORMAT_JSON;

            return [
                'button' => $this->renderPartial('/cart/button', ['cart_amount' => Order::count(supplies: true)]),
                '_csrf' => yii::$app->request->getCsrfToken()
            ];
        }
    }
}
