<?php


namespace App\Services;



use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\PerfilDAO;
use App\DAO\Pagination\Pagination;
use App\Mappers\PerfilMapper;
use App\Services\ServiceResponse\ServiceResponse;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\Utils\ResponseException;
use App\ViewModels\Perfil\PerfilDetailsViewModel\PerfilDetailsViewModel;
use App\ViewModels\Perfil\PerfilListingViewModel\PerfilListingViewModel;
use App\ViewModels\Perfil\PerfilRegistrationViewModel\PerfilRegistrationViewModel;

class PerfilService extends Service
{

    public function getPerfilList (?Pagination $pagination, ?QueryFilterCollection $query_filter_collection, ?QueryOrderCollection $query_order_collection = null) : ServiceResponse {
        $perfil_dao = new PerfilDAO();
        $dao_response = $perfil_dao->getPerfilList($pagination, $query_filter_collection, $query_order_collection);
        switch ($dao_response->getStatus()) {
            case DAOResponseInterface::SUCESS:
                $service_response_status = ServiceResponseInterface::SUCESS;
                break;
            case DAOResponseInterface::RECORD_NOT_FOUND:
                $service_response_status = ServiceResponseInterface::RECORD_NOT_FOUND;
                break;
            case DAOResponseInterface::DATABASE_CONNECTION_ERROR:
                $service_response_status = ServiceResponseInterface::DATABASE_CONNECTION_ERROR;
                break;
        }
        $service_response = ServiceResponse::builder()
            ->setStatus($service_response_status)
            ->build();
        if ($service_response_status === DAOResponseInterface::SUCESS) {
            $dao_response_data = $dao_response->getData();
            $perfil_details_array = PerfilMapper::getPerfilDetailsArrayFromPerfilDetailsVMList($dao_response_data);
            $pagination = $dao_response->getPagination();
            $data = [
                'perfis' => $perfil_details_array,
                'pagination' => $pagination ? $pagination->toResponseArray() : null
            ];
            $service_response->setData($data);
        }
        return $service_response;
    }

    public function getPerfilByID (int $id_perfil): ServiceResponse {
        $perfil_dao = new PerfilDAO();
        $log_service = new LogService();
        $dao_response = $perfil_dao->getPerfilDetailsByPerfilID($id_perfil);
        $service_response = new ServiceResponse;
        switch ($dao_response->getStatus()) {
            case DAOResponseInterface::SUCESS:
                $service_response->setStatus(ServiceResponseInterface::SUCESS);
                $perfil_details_vm = (function (PerfilDetailsViewModel $perfil_details_vm): PerfilDetailsViewModel {
                    return $perfil_details_vm;
                })($dao_response->getData());
                $perfil_id_response = $perfil_details_vm->getPerfilId();
                $service_response->setData($perfil_details_vm->toArray());
                break;
            case DAOResponseInterface::RECORD_NOT_FOUND:
                $service_response->setStatus(ServiceResponseInterface::RECORD_NOT_FOUND);
                break;
            default:
                $service_response->setStatus(ServiceResponseInterface::DATABASE_CONNECTION_ERROR);
                break;
        }
        return $service_response;
    }


    public function registerPerfil (array $data) : ServiceResponse {
        try {
            $perfil_registration_vm = PerfilMapper::PerfilRegistrationViewModelMapper($data);
        }catch (ResponseException $response_exception) {
            $log_service = new LogService();
            $log_service->log_error(ServiceResponseInterface::SERVICE_INTERNAL_ERROR,
                'Ocorreu um erro durante o mapeamento da entidade PerfilRegistrationViewModel',
                $response_exception->getData());
            return ServiceResponse::builder()
                ->setStatus(ServiceResponseInterface::SERVICE_INTERNAL_ERROR)
                ->setErrors($response_exception->getData())
                ->build();
        }
        $perfil_dao = new PerfilDAO();
        $dao_response = $perfil_dao->persistPerfilRegistrationVM($perfil_registration_vm);
        $service_response = new ServiceResponse;
        switch ($dao_response->getStatus()) {
            case DAOResponseInterface::SUCESS:
                $service_response->setStatus(ServiceResponseInterface::SUCESS);
                break;
            case DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS:
                break;
            case DAOResponseInterface::DUPLICATED_UNIQUE_KEY:
                $service_response->setStatus(ServiceResponseInterface::VALIDATION_PARAMS_ERROR);
                $service_response->setErrors($dao_response->getErrors());
                break;
            case DAOResponseInterface::INTERNAL_DAO_ERROR:
                $service_response->setStatus(ServiceResponseInterface::SERVICE_INTERNAL_ERROR);
                break;
            default:
                $service_response->setStatus(ServiceResponseInterface::DATABASE_CONNECTION_ERROR);
                break;
        }
        return $service_response;
    }

    public function updatePerfilData (int $id_perfil, array $data) : ServiceResponse {
        try {
            $perfil_update_vm = PerfilMapper::getPerfilUpdateVMFromArray($data);
            if  (count($perfil_update_vm->toArray(true)) === 0) {
                return ServiceResponse::builder()
                    ->setStatus(ServiceResponseInterface::INSUFFICIENT_DATA)
                    ->build();
            }
        }catch (ResponseException $response_exception) {
            $log_service = new LogService();
            $log_service->log_error(ServiceResponseInterface::SERVICE_INTERNAL_ERROR, 'Ocorreu um erro durante o mapeamento da entidade PerfilUpdateViewModel', $response_exception->getData());
            return ServiceResponse::builder()
                ->setStatus(ServiceResponseInterface::SERVICE_INTERNAL_ERROR)
                ->setErrors($response_exception->getData())
                ->build();
        }
        $perfil_dao = new PerfilDAO();
        $dao_response = $perfil_dao->persistPerfilUpdateVM($id_perfil, $perfil_update_vm);
        $service_response = new ServiceResponse;
        switch ($dao_response->getStatus()) {
            case DAOResponseInterface::SUCESS:
                $service_response->setStatus(ServiceResponseInterface::SUCESS);
                break;
            case DAOResponseInterface::DUPLICATED_UNIQUE_KEY:
                break;
            case DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS:
                $service_response->setStatus(ServiceResponseInterface::VALIDATION_PARAMS_ERROR);
                $service_response->setErrors($dao_response->getErrors());
                break;
            case DAOResponseInterface::DATABASE_CONNECTION_ERROR:
                $service_response->setStatus(ServiceResponseInterface::DATABASE_CONNECTION_ERROR);
                break;
        }
        return $service_response;
    }
}