<?php

namespace App\Services;

use App\DAO\PagamentoDAO;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\Pagination\Pagination;
use App\Mappers\PagamentoMapper;
use App\Services\ServiceResponse\ServiceResponse;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;

class PagamentoService extends Service {

	public function registerPagamento($pagamento): ServiceResponse {

		$pagamento_fechamento_vm = PagamentoMapper::getPagamentoFechamentoRegistrationVMfromFrom( $pagamento );
		$pagamento_lancamento_vm = PagamentoMapper::getPagamentoLancamentoRegistrationVMfromFrom( $pagamento );
		$formaPagamento = PagamentoMapper::getFormaPagamentoRegistrationVMfromFrom( $pagamento );

		$pagamento_comanda_vm = PagamentoMapper::getPagamentoComandaRegistrationVMfromFrom( $pagamento );

		$pagamento_dao = new PagamentoDAO();
		$dao_response = $pagamento_dao->persistPagamentoComandaRegistrationVM( $pagamento_fechamento_vm, $pagamento_lancamento_vm, $formaPagamento,
			$pagamento_comanda_vm );
		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$data = [ 
					'resultado' => $dao_response->getData()
				];
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				$service_response->setData( $data );
				break;
			case DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS :
			case DAOResponseInterface::DUPLICATED_UNIQUE_KEY :
				$service_response->setStatus( ServiceResponseInterface::VALIDATION_PARAMS_ERROR );
				$service_response->setErrors( $dao_response->getErrors() );
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				$data = [ 
					'resultado' => $dao_response->getData()
				];
				$service_response->setData( $data );
				$service_response->setStatus( ServiceResponseInterface::DATABASE_CONNECTION_ERROR );
				break;
		}
		return $service_response;

	}

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

		$procedimento_dao = new PagamentoDAO();
		$dao_response = $procedimento_dao->getProcedimentoList( $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();
			$procedimento_details_array = PagamentoMapper::getProcedimentosDetailsArrayFromProcedimentoDetailsVMCollection( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'procedimentos' => $procedimento_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

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

		$procedimento_dao = new PagamentoDAO();
		$dao_response = $procedimento_dao->getProcedimentoConsultaList( $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();
			$procedimento_details_array = PagamentoMapper::getProcedimentosDetailsArrayFromProcedimentoDetailsVMCollection( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'procedimentos' => $procedimento_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

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

		$procedimento_dao = new PagamentoDAO();
		$dao_response = $procedimento_dao->getProcedimentoInternacaoList( $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();
			$procedimento_details_array = PagamentoMapper::getProcedimentosDetailsArrayFromProcedimentoDetailsVMCollection( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'procedimentos' => $procedimento_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

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

		$procedimento_dao = new PagamentoDAO();
		$dao_response = $procedimento_dao->getProcedimentoMedicacaoList( $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();
			$procedimento_details_array = PagamentoMapper::getProcedimentosDetailsArrayFromProcedimentoDetailsVMCollection( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'procedimentos' => $procedimento_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

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

		$procedimento_dao = new PagamentoDAO();
		$dao_response = $procedimento_dao->getProcedimentoCirurgiaList( $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();
			$procedimento_details_array = PagamentoMapper::getProcedimentosDetailsArrayFromProcedimentoDetailsVMCollection( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'procedimentos' => $procedimento_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

	public function getProcedimento(QueryFilter $query_filter): ServiceResponse {

		$procedimento_dao = new PagamentoDAO();
		$query_filter_collection = new QueryFilterCollection();
		$query_filter_collection->push( $query_filter );
		$dao_response = $procedimento_dao->getṔrocedimento( $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 deleteProcedimento(int $id_procedimento): ServiceResponse {

		$procedimento_dao = new PagamentoDAO();
		$dao_response = $procedimento_dao->deleteProcedimento( $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 updateProcedimentoData(int $id_paciente, array $data): ServiceResponse {

		$paciente_update_vm = PagamentoMapper::getProcedimentoUpdateVMFromArray( $data );
		$paciente_dao = new PagamentoDAO();
		$dao_response = $paciente_dao->persistProcedimentoUpdateVM( $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 procedimento", [ ] );
			$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 formatValores($formasPagamentos) {

		$lista = $formasPagamentos;

		for($i = 0; $i < count( $lista ); $i++) {
			$dinheiro = $lista [$i]->dinheiro;
			$dinheiro_valor = strval( $dinheiro->valor );
			$dinheiro_troco = strval( $dinheiro->troco );
			$dinheiro_valor = str_replace( ',', '.', $dinheiro_valor );
			$dinheiro_troco = str_replace( ',', '.', $dinheiro_troco );
			$dinheiro->valor = $dinheiro_valor;
			$dinheiro->troco = $dinheiro_troco;
			$lista [$i]->dinheiro = $dinheiro;
			$valor = strval( $lista [$i]->valor );
			$valor = str_replace( ',', '.', $valor );
			$lista [$i]->valor = $valor;

			if (isset( $lista [$i]->creditocliente )) {
				$list = $lista [$i]->creditocliente;
				for($y = 0; $y < count( $list ); $y++) {
					$valor_total = strval( $list [$i]->valor_total );
					$valor_total = str_replace( ',', '.', $valor_total );
					$list [$i]->valor_total = $valor_total;
					$valor_usado = strval( $list [$i]->valor_usado );
					$valor_usado = str_replace( ',', '.', $valor_usado );
					$list [$i]->valor_usado = $valor_usado;
				}
				$lista [$i]->creditocliente = $list;
			}
		}

		return $lista;

	}

}