<?php

namespace common\logic\User\User\Service;

use common\logic\AbstractService;
use common\logic\SolverInterface;
use common\logic\User\User\Model\User;
use common\logic\User\UserGroup\Model\UserGroup;
use common\logic\User\UserUserGroup\Model\UserUserGroup;

class UserSolver extends AbstractService implements SolverInterface
{
    public function getTypeChoicesArray(): array
    {
        return [
            User::TYPE_INDIVIDUAL => 'Particulier',
            User::TYPE_LEGAL_PERSON => 'Personne morale',
            User::TYPE_GUEST => 'Visiteur'
        ];
    }

    public function getUsernameFromArray(array $modelArray, $withType = false): string
    {
        $username = '';
        if (isset($modelArray['name_legal_person']) && strlen($modelArray['name_legal_person'])) {
            $username = $modelArray['name_legal_person'];

            if ($withType) {
                $username = 'Personne morale / ' . $username;
            }
        } else {
            $username = $modelArray['lastname'] . ' ' . $modelArray['name'];
        }

        return $username;
    }

    public function getUsername(User $user, $withType = false): string
    {
        $username = '';
        if (isset($user->name_legal_person) && strlen($user->name_legal_person)) {
            $username = $user->name_legal_person;

            if ($withType) {
                $username = 'Personne morale / ' . $username;
            }
        } else {
            $username = $user->lastname . ' ' . $user->name;
        }

        return $username;
    }

    public function getFullAddress(User $user, $nl2br = false)
    {
        $address = '';
        if (isset($user->lastname) && isset($user->name) && strlen($user->lastname) && strlen($user->name)) {
            $address .= $user->lastname . ' ' . $user->name . "\n";
        }
        if (isset($user->name_legal_person) && strlen($user->name_legal_person)) {
            $address .= $user->name_legal_person . "\n";
        }
        $address .= $user->address;

        if ($nl2br) {
            $address = nl2br($address);
        }

        return $address;
    }

    /**
     * Finds out if password reset token is valid
     *
     * @param string $token password reset token
     * @return boolean
     */
    public function isPasswordResetTokenValid($token)
    {
        if (empty($token)) {
            return false;
        }
        $expire = \Yii::$app->params['user.passwordResetTokenExpire'];
        $parts = explode('_', $token);
        $timestamp = (int)end($parts);
        return $timestamp + $expire >= time();
    }

    /**
     * Retourne si l'utilisateur est un admin ou non.
     *
     */
    public function isAdmin(User $user): bool
    {
        return $user->status == User::STATUS_ADMIN;
    }

    /**
     * Retourne si l'utilisateur est un producteur ou non.
     *
     */
    public function isProducer(User $user): bool
    {
        return ($user->status == User::STATUS_ADMIN
                || $user->status == User::STATUS_PRODUCER) && $user->id_producer;
    }

    /**
     * Retourne l'utilisateur courant.
     *
     */
    public function getCurrent(): ?User
    {
        if (!\Yii::$app->user->isGuest) {
            return \Yii::$app->user->identity;
        }

        return null;
    }

    /**
     * Retourne si l'utilisateur courant est connecté ou non.
     *
     */
    public function isCurrentConnected(): bool
    {
        return !\Yii::$app->user->isGuest;
    }

    /**
     * Retourne si l'utilisateur courant est un producteur ou non.
     *
     */
    public function isCurrentProducer(): bool
    {
        $user = $this->getCurrent();
        if ($user) {
            return $this->isProducer($user);
        }
        return false;
    }

    /**
     * Retourne si l'utilisateur courant est un admin ou non.
     *
     */
    public function isCurrentAdmin(): bool
    {
        $user = $this->getCurrent();
        if ($user) {
            return $this->isAdmin($user);
        }
        return false;
    }

    /**
     * Retourne l'ID de l'utilisateur courant connecté.
     *
     */
    public function getCurrentId()
    {
        if (!\Yii::$app->user->isGuest) {
            return \Yii::$app->user->identity->id;
        }

        return false;
    }

    /**
     * Retourne le status de l'utilisateur courant connecté.
     *
     */
    public function getCurrentStatus()
    {
        if (!\Yii::$app->user->isGuest) {
            return \Yii::$app->user->identity->status;
        }

        return false;
    }

    public function hasAccessBackend(): bool
    {
        $userCurrentStatus = $this->getCurrentStatus();

        return $userCurrentStatus == User::STATUS_ADMIN
            || $userCurrentStatus == User::STATUS_PRODUCER;
    }

    // belongsToUserGroup
    public function isUserBelongsToUserGroup(User $user, UserGroup $userGroup): bool
    {
        if (!$user->userUserGroup) {
            $user->populateRelation('userUserGroup', UserUserGroup::searchAll([
                'id_user' => $user->id
            ]));
        }

        if ($user->userUserGroup) {
            foreach ($user->userUserGroup as $userUserGroup) {
                if ($userUserGroup->id_user_group == $userGroup->id) {
                    return true;
                }
            }
        }

        return false;
    }

}