<?php

declare(strict_types=1);

namespace app\controllers;

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 = yii::$app->user->identity;

        // Поиск корзины (текущего заказа)
        $model = Order::search();

        if (empty($model)) {
            // Корзина не инициализирована

            // Инициализация
            $model = new Order();

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

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

        // Инициализация содержимого корзины
        $connections = $model->content(10, $page);

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

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

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

        return $this->render('index', compact('model', 'connections'));
    }

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

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

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

            goto end;
        }

        if ($edges = OrderEdgeSupply::searchBySupplyCatn($catn, Order::search())) {
            // Рёбра найдены (связи заказа с поставкой)

            // Инициализация
            $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::searchByCatn($catn)) {
            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()
            ];
        }
    }
}
