<?php


namespace Shop\Application\Office\AuthCustomer;


use Core\Concrete\AuthFactory;
use Shop\Presentation\Config\Main;
use Shop\Infrastructure\Repositories\Customer\CustomerCriteria;
use Shop\Infrastructure\Repositories\Customer\CustomerRepository;
use Shop\Infrastructure\Repositories\CustomerGroup\CustomerGroupCriteria;
use Shop\Infrastructure\Repositories\CustomerGroup\CustomerGroupRepository;

class AuthCustomerHandler
{
    protected $customerRepository;
    protected $authFactory;
    protected $mainConfig;
    protected $customerGroupRepository;

    /**
     * AuthCustomerHandler constructor.
     * @param CustomerRepository $customerRepository
     * @param Main $mainConfig
     * @param CustomerGroupRepository $customerGroupRepository
     * @param AuthFactory $authFactory
     */
    public function __construct(CustomerRepository $customerRepository,
                                Main $mainConfig,
                                CustomerGroupRepository $customerGroupRepository,
                                AuthFactory $authFactory)
    {
        $this->customerRepository = $customerRepository;
        $this->authFactory = $authFactory;
        $this->mainConfig = $mainConfig;
        $this->customerGroupRepository = $customerGroupRepository;
    }

    /**
     * @param AuthCustomerCommand $command
     * @throws \Repo\Concrete\Exceptions\Collection
     */
    public function handle(AuthCustomerCommand $command): void
    {

        $password = $command->getPassword() > '' ? md5($command->getPassword()): $command->getHashPassword();

        $groups = $this->customerGroupRepository->findByCriteria(
            CustomerGroupCriteria::create()
        );


        if($command->getCustomerGroupId() !== null){
            $filteredGroups = [$command->getCustomerGroupId()];
        }
        else{
            $filteredGroups = array_diff(
                array_keys($groups->getDropdownList()),
                [$this->mainConfig->getDefaultGuestGroup(),$this->mainConfig->getDefaultContractorGroup()]
            );
        }

        $customers = $this->customerRepository->findByCriteria(
            CustomerCriteria::create()
                ->setFilterByEmail($command->getLogin())
                ->setFilterByBlocked(false)
                ->setFilterByGroupIds($filteredGroups)
                ->setFilterByPassword($password)
        );

        if($customers->count() > 1){
            throw new ManyCustomersException(sprintf('found %s customers', $customers->count()));
        }

        if($customers->count() === 0){
            throw new CustomerNotFoundException(sprintf('customer not found by login %s and password',$command->getLogin()));
        }

        $customer = $customers->current();

        //-------------------------------------------------------------------------------------------------------------
        $userdata = array(
            'customer_name' => $customer->getName(),
            'customer_id' => $customer->getId(),
            'customer_email' => $customer->getEmail()
        );

        $userName = md5(serialize($userdata));

        //авторизующий серсис
        $loginService = $this->authFactory->newLoginService();

        //объект авторизации
        $authService = $this->authFactory->newInstance();
        if ($authService->isAnon() || $authService->getUserName() !== $userName) {
            $loginService->forceLogin($authService, $userName, $userdata);
        }

        $customer->setLastAuth(time());

        $this->customerRepository->save($customer);
    }

}