<?php


namespace App\Services;

use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\Order\QueryOrder;
use App\DAO\CentroCustoDAO;
use App\DAO\Pagination\Pagination;
use App\Entities\CentroCusto\CentroCusto;
use App\Mappers\CentroCustoMapper;
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\CentroCusto\CentroCustoRegistrationViewModel\CentroCustoRegistrationViewModel;
use CodeIgniter\Model;
use Config\Paths;

// use phpDocumentor\Reflection\DocBlock\Tags\Var_;
class CentroCustoService extends Service {

	public function registerCentroCusto(array $data): ServiceResponse {

		try {
			$paciente_registration_vm = CentroCustoMapper::CentroCustoRegistrationViewModelMapper( $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 CentroCustoRegistrationViewModel', $response_exception->getData() );
			return ServiceResponse::builder()->setStatus( ServiceResponseInterface::SERVICE_INTERNAL_ERROR )
				->setErrors( $response_exception->getData() )
				->build();
		}
		$paciente_dao = new CentroCustoDAO();
		$dao_response = $paciente_dao->persistCentroCustoRegistrationVM( $paciente_registration_vm );
		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				$paciente = (function (CentroCusto $paciente): CentroCusto {
					return $paciente;
				})( $dao_response->getData() );
				$service_response->setData( [ 
						'id_centro_custo' => $paciente->getId()
				] );
				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 getCentroCustoList(?Pagination $pagination, ?QueryFilterCollection $query_filter_collection,
			?QueryOrderCollection $query_order_collection = null): ServiceResponse {

		$paciente_dao = new CentroCustoDAO();
		$dao_response = $paciente_dao->getCentroCustoList( $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();
			$paciente_details_array = CentroCustoMapper::getCentroCustosDetailsArrayFromCentroCustoDetailsVMList( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
					'centro_custo' => $paciente_details_array,
					'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

	public function getCentroCusto(QueryFilter $query_filter): ServiceResponse {

		$paciente_dao = new CentroCustoDAO();
		$query_filter_collection = new QueryFilterCollection();
		$query_filter_collection->push( $query_filter );
		$dao_response = $paciente_dao->getCentroCusto( $query_filter_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) {
			$service_response->setData( $dao_response->getData()
				->toArray() );
		}
		return $service_response;

	}

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

		try {
			$paciente_update_vm = CentroCustoMapper::getCentroCustoUpdateVMFromArray( $data );
			if (count( $paciente_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 CentroCustoUpdateViewModel', $response_exception->getData() );
			return ServiceResponse::builder()->setStatus( ServiceResponseInterface::SERVICE_INTERNAL_ERROR )
				->setErrors( $response_exception->getData() )
				->build();
		}

		$paciente_dao = new CentroCustoDAO();
		$dao_response = $paciente_dao->persistCentroCustoUpdateVM( $id_paciente, $paciente_update_vm );
		$service_response = new ServiceResponse();

		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				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;

	}

	public function deleteCentroCusto(int $id_centro_custo): ServiceResponse {

		$paciente_dao = new CentroCustoDAO();
		$dao_response = $paciente_dao->persistCentroCustoDeleteVM( $id_centro_custo );
		$service_response = new ServiceResponse();

		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				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;

	}

}