<?php

namespace App\Services;

use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\Pagination\Pagination;
use App\DAO\EspecialidadeDAO;
use App\Mappers\EspecialidadeMapper;
use App\Services\ServiceResponse\ServiceResponse;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\GeneralCollection;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\Utils\ResponseException;

class EspecialidadeService extends Service {

	public function registerEspecialidade(array $data): ServiceResponse {

		$especialidade_registration_vm = EspecialidadeMapper::getEspecialidadeRegistrationViewModelFromArray( $data );
		$especialidade_dao = new EspecialidadeDAO();
		$dao_response = $especialidade_dao->persistEspecialidadeRegistrationVM( $especialidade_registration_vm );
		$service_response = ServiceResponse::builder()->build();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$data = [ 
					'id_especialidade' => $dao_response->getData()
						->getId() ];
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				$service_response->setData( $data );
				break;
			case DAOResponseInterface::DUPLICATED_UNIQUE_KEY :
				$service_response->setStatus( ServiceResponseInterface::VALIDATION_PARAMS_ERROR );
				$service_response->setErrors( [ 
					'descricao' => 'Esse tipo de procedimento já existe.' ] );
				break;
		}
		return $service_response;

	}

	public function getEspecialidadeList(?Pagination $pagination, ?QueryFilterCollection $query_filter_collection, ?QueryOrderCollection $query_order_collection): ServiceResponse {

		$especialidade_dao = new EspecialidadeDAO();
		$dao_response = $especialidade_dao->getEspecialidadeList( $pagination, $query_filter_collection, $query_order_collection );
		$service_response_status = [ 
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND,
			DAOResponseInterface::DATABASE_CONNECTION_ERROR => ServiceResponseInterface::DATABASE_CONNECTION_ERROR ] [$dao_response->getStatus()];
		$service_response = ServiceResponse::builder()->setStatus( $service_response_status )
			->build();
		if ($service_response_status === ServiceResponseInterface::SUCESS) {
			$especialidade_details_vm_collection = (function (GeneralCollection $collection): GeneralCollection {
				return $collection;
			})( $dao_response->getData() );
			$pagination = $dao_response->getPagination();
			$especialidade_details_array = $especialidade_details_vm_collection->toArray();

			$data = [ 
				'especialidades' => $especialidade_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null ];

			// $service_response->setData($especialidade_details_array);

			$service_response->setData( $data );
		}
		return $service_response;

	}

	public function deleteEspecialidade(int $id_procedimento): ServiceResponse {

		$especialidade_dao = new EspecialidadeDAO();
		$dao_response = $especialidade_dao->deleteEspecialidade( $id_procedimento );
		$service_response_status = [ 
			DAOResponseInterface::RESTRICT_FK_UPDATE_OR_DELETION => ServiceResponseInterface::RECORD_IS_LINKED,
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND ] [$dao_response->getStatus()];

		$service_response = ServiceResponse::builder()->setStatus( $service_response_status )
			->build();
		return $service_response;

	}

	public function getEspecialidade(QueryFilter $query_filter): ServiceResponse {

		$especie_dao = new EspecialidadeDAO();
		$query_filter_collection = new QueryFilterCollection();
		$query_filter_collection->push( $query_filter );
		$dao_response = $especie_dao->getEspecialidade( $query_filter_collection );
		$service_response_status = [ 
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND,
			DAOResponseInterface::DATABASE_CONNECTION_ERROR => ServiceResponseInterface::DATABASE_CONNECTION_ERROR ] [$dao_response->getStatus()];
		$service_response = ServiceResponse::builder()->setStatus( $service_response_status ?? ServiceResponseInterface::UNKNOWN_ERROR)
			->build();
		if ($service_response_status === ServiceResponseInterface::SUCESS) {
			$service_response->setData( $dao_response->getData()
				->toArray() );
		}
		return $service_response;

	}

	public function updateEspecialidadeData(int $id_paciente, array $data): ServiceResponse {

		$paciente_update_vm = EspecialidadeMapper::getEspecialidadeUpdateVMFromArray( $data );
		$paciente_dao = new EspecialidadeDAO();
		$dao_response = $paciente_dao->persistEspecialidadeUpdateVM( $id_paciente, $paciente_update_vm );
		$service_response = new ServiceResponse();
		$response_status = [ 
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND,
			DAOResponseInterface::DATABASE_CONNECTION_ERROR => ServiceResponseInterface::DATABASE_CONNECTION_ERROR,
			DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS => ServiceResponseInterface::VALIDATION_PARAMS_ERROR,
			DAOResponseInterface::DUPLICATED_UNIQUE_KEY => ServiceResponseInterface::VALIDATION_PARAMS_ERROR ] [$dao_response->getStatus()];
		if (!$response_status) {
			(new LogService())->log_error( $response_status, "Ocorreu um erro desconhecido durante a atualização o especie", [ ] );
			$response_status = ServiceResponseInterface::DATABASE_CONNECTION_ERROR;
		} else if ($response_status !== ServiceResponseInterface::SUCESS) {
			$service_response->setErrors( $dao_response->getErrors() );
		}
		$service_response->setStatus( $response_status );
		return $service_response;

	}

	public function getEspecialidadeListByUnidadeId(int $id_unidade): ServiceResponse {

		$service_response = new ServiceResponse();
		$dao = new EspecialidadeDAO();
		$dao_response = $dao->getEspecialidadeListByUnidadeId( $id_unidade );

		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				$service_response->setData( $dao_response->getData() );
				break;
			case DAOResponseInterface::RECORD_NOT_FOUND :
				$service_response->setStatus( ServiceResponseInterface::RECORD_NOT_FOUND );
				$service_response->setData( [ ] );
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				$service_response->setStatus( ServiceResponseInterface::DATABASE_CONNECTION_ERROR );
				$service_response->setErrors( $dao_response->getErrors() );
				break;
			default :
				$service_response->setStatus( ServiceResponseInterface::UNKNOWN_ERROR );
				$service_response->setErrors( $dao_response->getErrors() );
				break;
		}
		
		return $service_response;

	}

}