<?php

namespace Src\Modules\Auth\Application\Admin;

use Src\Common\Application\TraitDomain;
use Src\Common\Application\ResponsesCode;
use Src\Modules\Auth\Interfaces\Application\Admin\IDomain;
use Src\Modules\Auth\Interfaces\Application\Admin\IValidator;
use Illuminate\Support\Facades\Auth;
use Src\Modules\Auth\Interfaces\Dto\Admin\IFactory as IAdminDtoFactory;
use Src\Modules\Auth\Interfaces\Infrastructure\PersistLayer\IAdminsLayer;
use Src\Modules\Auth\Interfaces\Infrastructure\Storage\IAdminsStorage;

class Domain implements IDomain
{
    use TraitDomain;

    private IValidator $validator;

    protected IAdminDtoFactory $adminDtoFactory;

    protected IAdminsLayer $adminsLayer;

    protected IAdminsStorage $adminsStorage;

    public function setValidator(IValidator $validator): void
    {
        $this->validator = $validator;
    }

    public function setAdminDtoFactory(IAdminDtoFactory $factory): void
    {
        $this->adminDtoFactory = $factory;
    }

    public function setAdminsLayer(IAdminsLayer $layer): void
    {
        $this->adminsLayer = $layer;
    }

    public function setAdminsStorage(IAdminsStorage $storage): void
    {
        $this->adminsStorage = $storage;
    }

    public function login(array $data):bool
    {
        if($this->validator->login($data)){
            $cleanData = $this->validator->getCleanData();
            $cleanData['type'] = 'admin';
            if(Auth::attempt($cleanData)){
                return true;
            }else{
                $this->responseCode = ResponsesCode::NOT_AUTHORIZE_CODE;
                $this->errors = array_merge_recursive($this->errors, ['mail' => ['Неверный пароль']]);
                return false;
            }
        }else{
            $this->errors = $this->validator->getErrors();
            $this->responseCode = ResponsesCode::VALIDATION_FAILED_CODE;
            return false;
        }
    }

    public function insert(array $data): bool
    {
        if(!$this->validator->insert($data)){
            $this->responseCode = ResponsesCode::VALIDATION_FAILED_CODE;
            $this->errors = $this->validator->getErrors();
            return false;
        }
        $cleanData = $this->validator->getCleanData();
        $admin = $this->adminDtoFactory->createAdminPersist();
        $admin->load($cleanData);
        $this->adminsLayer->insert($admin);
        return true;
    }

    public function update(array $data): bool
    {
        if(!$this->validator->update($data)){
            $this->responseCode = ResponsesCode::VALIDATION_FAILED_CODE;
            $this->errors = $this->validator->getErrors();
            return false;
        }
        $cleanData = $this->validator->getCleanData();
        $adminData = $this->adminsStorage->getById($cleanData['id']);
        $admin = $this->adminDtoFactory->createAdminPersist();
        $admin->load($adminData);
        $admin->update($cleanData);
        $this->adminsLayer->update($admin);
        return true;
    }

    public function delete(string $id): bool
    {
        $result = $this->adminsLayer->delete($id);
        return boolval($result);
    }
}