<?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 yii\web\UploadedFile;

use app\models\Supply;
use app\models\SupplyGroup;
use app\models\Search;
use app\models\Notification;
use app\models\Settings;
use app\models\SettingsEdgeSettings;

class ProfileController extends Controller
{
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                        'actions' => ['index', 'supplies', 'import', 'monitoring', 'readGroups'],
                    ],
                    [
                        'allow' => false,
                        'roles' => ['?'],
                        'denyCallback' => [$this, 'accessDenied']
                    ],
                    [
                        'allow' => true,
                        'actions' => ['trusted', 'trusted-notification-write'],
                        'matchCallback' => function ($rule, $action) {
                            return yii::$app->user->identity->trst;
                        }
                    ]
                ]
            ]
        ];
    }

    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' => '/authentication',
                '_csrf' => Yii::$app->request->getCsrfToken()
            ]);
        } else if (Yii::$app->request->isGet) {
            // GET-запрос

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

    /**
     * Страница с настройками аккаунта
     */
    public function actionIndex(): string|array
    {
        // Инициализация
        $model = yii::$app->user->identity;
        $supplies = Supply::searchByAccount(select: 'supply.onec["ЗначенияСвойств"]');

        if ($vars = yii::$app->request->post('Account') ?? yii::$app->request->get('Account')) {
            // Обнаружены входные параметры

            if (isset($vars['opts'])) {
                // Переданы параметры

                // Инициализация
                is_array($model->opts) || $model->opts = [];

                // Запись
                $model->opts = array_merge($model->opts, $vars['opts']);

                $model->update();
            } else {
                /**
                 * @todo Написать обработчик ошибок
                 */
            }
        }

        // Генерация
        $sidebar = $this->renderPartial('sidebar');

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

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

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

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

    /**
     * Страница поставок
     */
    public function actionSupplies(): string|array
    {
        // Инициализация
        $model = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));

        // Генерация
        $sidebar = $this->renderPartial('sidebar');

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

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

            return [
                'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
                'redirect' => '/profile/supplies',
                '_csrf' => yii::$app->request->getCsrfToken()
            ];
        }

        return $this->render('supplies', compact('model', 'sidebar'));
    }

    /**
     * Страница панели управления для доверенных пользователей
     */
    public function actionTrusted(): string|array
    {
        // Инициализация
        $model_notifications = null;
        $model_settings = Settings::readLast();

        if (!is_null($vars = yii::$app->request->post('Notification') ?? yii::$app->request->get('Notification'))) {
            // Обнаружены входные параметры из раздела "Уведомления"

            // Реинициализация с новыми параметрами
            $model_notifications = new Notification($vars);

            // Запись уведомления и отправка (запись ребра до аккаунта)
            $model_notifications->write();
        } else if (!is_null($vars = yii::$app->request->post('Settings') ?? yii::$app->request->get('Settings'))) {
            // Обнаружены входные параметры из раздела "Настройки"

            if ($to = new Settings($vars)) {
                // Настройки инициализированы

                // Отправка
                if ($to->save()) {
                    // Сохранено в базе данных

                    // Буфер
                    $from = $model_settings;

                    // Реинициализация (для представления)
                    $model_settings = $to;

                    if ($from) {
                        // Найдена старая версия настроек

                        // Запись ребра: НАСТРОЙКИ (старые) -> НАСТРОЙКИ (новые)
                        SettingsEdgeSettings::write($from->readId(), $to->readId(), 'update');
                    }
                } else {
                    // Не сохранено в базе данных

                    // Запись ошибок
                    $model_settings->addErrors($to->getErrors());
                }
            }
        }

        // Деинициализация
        unset($vars);

        // Генерация
        $sidebar = $this->renderPartial('sidebar');

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

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

            return [
                'main' => $this->renderPartial('trusted', compact('model_notifications', 'model_settings', 'sidebar')),
                'redirect' => '/profile/trusted',
                '_csrf' => yii::$app->request->getCsrfToken()
            ];
        }

        return $this->render('trusted', compact('model_notifications', 'model_settings', 'sidebar'));
    }


    /**
     * Страницка панели управления для доверенных пользователей
     *
     * @todo Перенести в уведомления
     */
    // public function actionTrustedNotificationWrite(): string|array
    // {
    //     // Инициализация
    //     $model = new Notification(yii::$app->request->post('Notification') ?? yii::$app->request->get('Notification'));

    //     $model->write();

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

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

    //         return [
    //             'main' => $this->renderPartial('trusted', compact('model', 'sidebar')),
    //             'redirect' => '/profile/trusted',
    //             '_csrf' => yii::$app->request->getCsrfToken()
    //         ];
    //     }

    //     return $this->render('trusted', compact('model', 'sidebar'));
    // }

    /**
     * Страницка панели управления для доверенных пользователей
     */
    public function actionMonitoring(): string|array
    {

        // Инициализация номера страницы
        $page_search_history = (yii::$app->request->post('search') ?? yii::$app->request->get('search')) - 1;
        if ($page_search_history <= 0) {
            $page_search_history = 0;
        }

        // Инициализация количества строк на одной странице
        $rows_amount = 10;

        // Генерация
        $sidebar = $this->renderPartial('sidebar');
        $search_history = Search::searchByAccount(yii::$app->user->id, $rows_amount, ((int) $page_search_history ?? 0) * $rows_amount);

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

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

            return [
                'main' => $this->renderPartial('monitoring', compact(
                    'sidebar',
                    'search_history',
                    'page_search_history'
                )),
                'search' => $page_search_history + 1,
                'redirect' => '/profile/monitoring',
                '_csrf' => yii::$app->request->getCsrfToken()
            ];
        }

        return $this->render('monitoring', compact(
            'sidebar',
            'search_history',
            'page_search_history'
        ));
    }

    public function actionImport()
    {
        // Инициализация
        $model = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
        $model->scenario = $model::SCENARIO_IMPORT;

        // Генерация
        $sidebar = $this->renderPartial('sidebar');

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

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

            $model->file = UploadedFile::getInstances($model, 'file');

            if (!$test = $model->import()) {
                yii::$app->response->statusCode = 409;
            }

            return [
                'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
                '_csrf' => yii::$app->request->getCsrfToken()
            ];
        }

        return $this->render('supplies', compact('model', 'sidebar'));
    }

    public static function readGroups()
    {
        // Инициализация
        $groups = [];

        foreach (SupplyGroup::readAll() as $group) {
            // Перебор всех групп

            // Генерация [КЛЮЧ => ИМЯ]
            $groups[$group->_key] = $group->name;
        }

        return $groups;
    }
}
