<?php

declare(strict_types=1);

namespace app\models;

use Yii;
use yii\web\IdentityInterface;

use carono\exchange1c\interfaces\PartnerInterface;

/**
 * Аккаунт
 *
 * Реализует аккаунты пользователей и поставщиков
 */
class Account extends Document implements IdentityInterface, PartnerInterface
{
    /**
     * Имя коллекции
     */
    public static function collectionName(): string
    {
        return 'account';
    }

    /**
     * Свойства
     */
    public function attributes(): array
    {
        return array_merge(
            parent::attributes(),
            [
                'auth',
                'mail',
                'pswd',
                'name',
                'simc',
                'sity',
                'comp',
                'taxn',
                'onec',
                'opts',
                'trst'
            ]
        );
    }

    /**
     * Метки свойств
     */
    public function attributeLabels(): array
    {
        return array_merge(
            parent::attributeLabels(),
            [
                'auth' => 'Аутентификационный хеш',
                'mail' => 'Почта',
                'pswd' => 'Пароль',
                'name' => 'Имя',
                'simc' => 'Номер',
                'sity' => 'Город',
                'comp' => 'Компания',
                'taxn' => 'ИНН',
                'onec' => 'Данные 1C',
                'opts' => 'Параметры',
                'trst' => 'Доверенный пользователь'
            ]
        );
    }

    /**
     * Правила
     */
    public function rules(): array
    {
        return array_merge(
            parent::rules(),
            [
                [['mail', 'pswd'], 'required', 'message' => 'Заполните поле'],
                ['mail', 'email'],
                [['mail', 'comp', 'simc'], 'unique', 'message' => '2']
            ]
        );
    }

    /**
     * Перед сохранением
     *
     * @todo Подождать обновление от ебаного Yii2 и добавить
     * проверку типов передаваемых параметров
     */
    public function beforeSave($data): bool
    {
        if (parent::beforeSave($data)) {
            if ($this->isNewRecord) {
                $this->auth = Yii::$app->security->generateRandomString();
            }

            return true;
        }
        return false;
    }

    /**
     * Чтение полей для экспорта из 1С
     */
    public function getExportFields1c($context = null): array
    {
        return [];
    }

    /**
     * Чтение идентификатора
     *
     * @see IdentityInterface
     */
    public function getId(): string
    {
        return self::collectionName() . '/' . $this->_key;
    }

    /**
     * Чтение идентификатора
     */
    public function readId(): string
    {
        return $this->getId();
    }

    /**
     * Чтение аутентификационного ключа
     */
    public function getAuthKey(): string
    {
        return $this->auth;
    }

    /**
     * Идентификация
     *
     * @todo Подождать обновление от ебаного Yii2 и добавить
     * проверку типов передаваемых параметров
     */
    public static function findIdentity($_id): self
    {
        return static::findById($_id);
    }

    /**
     * Поиск по ключу
     *
     * @todo Подождать обновление от ебаного Yii2 и добавить
     * проверку типов передаваемых параметров
     */
    public static function findIdentityByAccessToken($pass, $type = null): self
    {
        return static::findOne(['pass' => $pass]);
    }

    /**
     * Поиск по почте
     *
     * @todo Подождать обновление Yii2 и добавить
     * проверку типов передаваемых параметров
     */
    public static function findByMail($mail): self
    {
        return static::findOne(['mail' => $mail]);
    }

    /**
     * Поиск по идентификатору
     *
     * @todo Подождать обновление Yii2 и добавить
     * проверку типов передаваемых параметров
     */
    public static function findById($_id): self
    {
        return static::searchById($_id);
    }

    /**
     * Проверка почты
     */
    public static function validateMail(string $mail): bool
    {
        if (static::findByMail($mail)) {
            // Почта найдена в базе данных

            return true;
        }

        return false;
    }

    /**
     * Проверка пароля
     */
    public function validatePassword(string $pswd): bool
    {
        return Yii::$app->security->validatePassword($pswd, $this->pswd);
    }

    /**
     * Проверка аутентификационного ключа
     *
     * @todo Подождать обновление Yii2 и добавить
     * проверку типов передаваемых параметров
     */
    public function validateAuthKey($auth): bool
    {
        return $this->getAuthKey() === $auth;
    }

    /**
     * Записать параметр
     *
     * @param string $name Название параметра
     * @param mixed $value Значение параметра
     */
    public function writeOption(string $name, mixed $value = null): bool
    {
        // Запись
        $this->opts[$name] = $value;

        // Отправка
        return $this->save();
    }

    /**
     * Удалить параметр
     *
     * @param string $name Название параметра
     */
    public function deleteOption(string $name): bool
    {
        // Удаление
        unset($this->opts[$name]);

        // Отправка
        return $this->save();
    }
}
