<?php

namespace App\Controllers;

use App\DAO\Filter\QueryFilterTranslator;
use App\DAO\Order\QueryOrder;
use App\DAO\Order\QueryOrderTranslator;
use App\DAO\Pagination\Pagination;
use App\Services\AgendaEspecialidadeService;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\DateUtils;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\Validations\AgendaEspecialidadeDisponibilidadeValidator;
use App\Validations\AgendaEspecialidadeValidation;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;
use Exception;

class AgendaEspecialidadeController extends BaseController {

	public function registerAgendaEspecialidade() {

		if (!$this->validate( AgendaEspecialidadeValidation::register() )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$agenda_service_response = (new AgendaEspecialidadeService())->registerAgendaEspecialidade( $_POST );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A agenda foi cadastrada com sucesso.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Não foi possível cadastrar a agenda, pois foram detectados conflitos com horários já cadastrados.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function registerMultipleAgendaEspecialidade() {

		if (!$this->validate( AgendaEspecialidadeValidation::multipleRegister() )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$agenda_service_response = (new AgendaEspecialidadeService())->registerMultipleAgendaEspecialidade( $_POST );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::PARTIAL_SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Alguns horários foram cadastrados com sucesso. Outros conflitaram com horários já cadastrados.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Não foi possível cadastrar os horários da agenda, pois todos os horários gerados conflitaram com horários já cadastrados no sistema.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Todos os horários foram cadastrados com sucesso.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function getAgendaEspecialidade(): Response {

		$filters = $_GET;
		if (isset( $filters ['id_unidade'] ) && !$filters ['id_unidade']) {
			unset( $filters ['id_unidade'] );
		}
		$query_filter_collection = new QueryFilterCollection( $filters, QueryFilterTranslator::agenda_especialidade() );
		$pagination = $this->getPaginationFromRequest();
		$query_order_collection = new QueryOrderCollection();
		$query_order_collection->push( 
			QueryOrder::builder()->setTable( 'agenda_especialidade' )
				->setNameParam( 'data' )
				->setDesc( $_GET ['sort'] === '-' )
				->build() );
		$query_order_collection->push( 
			QueryOrder::builder()->setTable( 'agenda_especialidade' )
				->setNameParam( 'hora_inicio' )
				->setDesc( $_GET ['sort'] === '-' )
				->build() );
		$agenda_service_response = (new AgendaEspecialidadeService())->getAgendaEspecialidadeListByMedicoID( $query_filter_collection, $pagination,
			$query_order_collection );
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados das agendas foram encontrados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'Nenhum registro foi encontrado.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function getAgendaUnidadeByEspecialidade(int $id_especialidade, int $id_unidade, int $data_inicial, int $data_final): Response {

		$pagination = $this->getPaginationFromRequest();

		if (is_null( $pagination )) {
			$pagination = Pagination::builder()->setCurrentPage( 1 )
				->setPerPage( 15 )
				->build();
		}

		$service = new AgendaEspecialidadeService();
		$service_response = $service->getAgendaUnidadeByEspecialidade( $id_especialidade, $id_unidade, $data_inicial, $data_final, $pagination );

		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados das agendas foram encontrados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'Nenhum registro foi encontrado.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];

		return $this->getResponse( $service_response, $response_messages );

	}

	public function deleteAgendaEspecialidade(int $id_agenda): Response {

		$agenda_service_response = (new AgendaEspecialidadeService())->deleteAgendaEspecialidade( $id_agenda );
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A exclusão foi efetuda com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'Nenhum registro foi encontrado.'
			],
			ServiceResponseInterface::RECORD_IS_LINKED => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Essa agenda está vinculada a outros cadastros do sistema. Portanto, não pode ser excluída.'
			],
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function updateAgendaEspecialidade(int $id_agenda): Response {

		if (!$this->validate( AgendaEspecialidadeValidation::update() )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$agenda_service_response = (new AgendaEspecialidadeService())->updateAgendaEspecialidade( $id_agenda, $_POST );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'A agenda não foi encontrada.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados da agenda foram atualizados com sucesso.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function registerAgendaEspecialidadeDisponibilidade(): Response {

		$request = $this->getDataPost();

		if (count( AgendaEspecialidadeDisponibilidadeValidator::register( $request ) ) > 0) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => AgendaEspecialidadeDisponibilidadeValidator::register( $request )
			] );
		}

		$agenda_service = new AgendaEspecialidadeService();
		$agenda_service_response = $agenda_service->registerAgendaEspecialidadeDisponibilidade( $request );

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A agenda foi cadastrada com sucesso.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_CONFLICT,
				'message' => 'Não foi possível cadastrar a agenda, pois foram detectados conflitos com horários já cadastrados.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::UNKNOWN_ERROR => [ 
				'code' => ResponseInterface::HTTP_MULTI_STATUS,
				'message' => 'O processo retornou multiplas mensagens.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function getAgendaEspecialidadeDisponibilidade(int $idUnidade, int $idEspecialidade, int $dataInicial, int $dataFinal): Response {

		if (count( AgendaEspecialidadeDisponibilidadeValidator::searchDisponibilidadePeriodo( $dataInicial, $dataFinal ) ) > 0) {
			return $this->response->setStatusCode( 400 )
				->setJSON( 
				[ 
					'message' => 'Informe os dados corretamente.',
					'errors' => AgendaEspecialidadeDisponibilidadeValidator::searchDisponibilidadePeriodo( $dataInicial, $dataFinal )
				] );
		}

		$agenda_service = new AgendaEspecialidadeService();
		$agenda_service_response = $agenda_service->getAgendaEspecialidadeDisponibilidade( $idUnidade, $idEspecialidade, $dataInicial, $dataFinal );

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A agenda foi cadastrada com sucesso.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_CONFLICT,
				'message' => 'Não foi possível cadastrar a agenda, pois foram detectados conflitos com horários já cadastrados.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::UNKNOWN_ERROR => [ 
				'code' => ResponseInterface::HTTP_MULTI_STATUS,
				'message' => 'O processo retornou multiplas mensagens.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function updateAgendaEspecialidadeDisponibilidade(): Response {

		$request = $this->getDataPost();

		if (count( AgendaEspecialidadeDisponibilidadeValidator::update( $request ) ) > 0) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => AgendaEspecialidadeDisponibilidadeValidator::update( $request )
			] );
		}

		$agenda_service = new AgendaEspecialidadeService();
		$agenda_service_response = $agenda_service->updateAgendaEspecialidadeDisponibilidade( $request );

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A status da agenda alterado com sucesso.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_CONFLICT,
				'message' => 'Não foi possível alterar o status da agenda.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::UNKNOWN_ERROR => [ 
				'code' => ResponseInterface::HTTP_MULTI_STATUS,
				'message' => 'O processo retornou multiplas mensagens.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function getAgendaEspecialidadeByUnidadeAndData() {

		$uri = explode( '/', $_SERVER ['REQUEST_URI'] );
		$unidadeId = ( int ) $uri [4] ?? 0;
		$date = $uri [6] ?? '1900-01-01';
		if (!$unidadeId || $date === '1900-01-01') {
			return $this->response->setStatusCode( 404 );
		}
		$sql = <<<SQL
		    SELECT
		        a.id as agenda_id
		        ,a.`data` as data
		        ,a.hora_inicio hora_inicio
		        ,a.hora_final hora_final 
		        ,med.id as medico_id
		        ,pf.nome as medico_nome
		        ,id_unidade as unidade_id
		        ,a.id_tipo_procedimento as tipo_procedimento_id 
		        ,tp.descricao as tipo_procedimento_descricao
		    FROM agenda a
		    INNER JOIN medico med on med.id = a.id_medico  
		    INNER JOIN profissional pro on pro.id = med.id_profissional
		    INNER JOIN pessoa pes on pes.id = pro.id_pessoa
		    INNER JOIN pessoa_fisica pf on pf.id_pessoa = pes.id
		    INNER JOIN tipo_procedimento tp on tp.id = a.id_tipo_procedimento 
		    LEFT JOIN agendamento ag on ag.id_agenda = a.id
		    WHERE 1=1
		        AND ag.id is null
		        and a.id_unidade = :unidade_id:
		        and a.`data` = :data:
		    order by `data`, hora_inicio
		SQL;
		$data = db_connect()->query( $sql, [ 
			'unidade_id' => $unidadeId,
			'data' => $date
		] )
			->getResultArray();
		return $this->response->setStatusCode( count( $data ) > 0 ? 200 : 404 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $data
		] );

	}

	public function getAgendaEspecialidadeByUnidade(int $unidade) {

		$sql = <<<SQL
		    select distinct id_especialidade , e.descricao
			from especialidade_procedimento ep2, especialidade e
			where ep2.id_unidade = :id_unidade: and ep2.id_especialidade = e.id 
		SQL;

		$binds = [ 
			'id_unidade' => $unidade
		];
		
		$conn = db_connect();
		$result = $conn->query($sql, $binds)->getResultArray();
		$errors = $conn->error();
		
		if ($errors ['code'] != 0) {
			return $this->response->setStatusCode( 400 )
			->setJSON( [
					'message' => 'parametros incorretos.',
					'data' => $errors
			] );
		}
		
		return $this->response->setStatusCode( count( $result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'pesquisa realizada com sucesso.',
			'data' => $result
		] );

	}

	public function getAgendaEspecialidadeByUnidadeByPeriodo(int $especialidade, int $unidade, int $datainicial) {

		$data = DateUtils::requestInt_to_date( $datainicial );

		if ($data == 'falso') {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => 'Data inválida'
			] );
		}

		$agenda_service = new AgendaEspecialidadeService();
		$agenda_service_response = $agenda_service->getAgendaEspecialidadeByUnidadeByPeriodo( $unidade, $especialidade, $data );
		$code = ResponseInterface::HTTP_INTERNAL_SERVER_ERROR;
		$msg = 'Erro interno';

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'A agenda não foi encontrada.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados da agenda foram atualizados com sucesso.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			]
		];

		switch ($agenda_service_response->getStatus()) {
			case ServiceResponseInterface::SUCESS :
				$code = ResponseInterface::HTTP_OK;
				$msg = 'Os dados da agenda encontrados com sucesso.';
				break;
			case ServiceResponseInterface::VALIDATION_PARAMS_ERROR :
				$code = ResponseInterface::HTTP_BAD_REQUEST;
				$msg = 'Informe os dados corretamente.';
				break;
			case ServiceResponseInterface::RECORD_NOT_FOUND :
				$code = ResponseInterface::HTTP_PARTIAL_CONTENT;
				$msg = 'A agenda não foi encontrada.';
				break;
		}
		return $this->response->setStatusCode( $code )
			->setJSON( [ 
			'message' => $msg,
			'data' => $agenda_service_response->getData()
		] );

		// return $this->getResponse( $agenda_service_response, $response_messages );
	}

	public function registerNewAgendamentoEspecialidadeByRecepcao() {

		$dados = $this->getDataPost();
		$idAgenda = 0;
		$idPet = 0;
		$idProcedimento = 0;
		$idObservacao = '';
		$idStatus = 1;
		if (!isset( $dados ['id_agenda_especialidade'] ) || !isset( $dados ['id_procedimento'] ) || !isset( $dados ['id_pet'] )) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		try {
			$idAgenda = intval( $dados ['id_agenda_especialidade'] );
			$idProcedimento = intval( $dados ['id_procedimento'] );
			$idPet = intval( $dados ['id_pet'] );
			$idObservacao = trim( $dados ['observacao'] );
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		$agenda_service = new AgendaEspecialidadeService();

		$agenda_service_response = $agenda_service->registerNewAgendamentoEspecialidadeByRecepcao( $idAgenda, $idProcedimento, $idPet, $idStatus, $idObservacao );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A agenda foi cadastrada com sucesso.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Não foi possível cadastrar a agenda, pois foram detectados conflitos com horários já cadastrados.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function updateStatusAgendamentoEspecialidadeByRecepcao(): Response {

		$dados = $this->getDataPost();

		$idAgenda = 0;
		$idObservacao = '';
		$idStatus = 0;

		if (!isset( $dados ['id_agenda_especialidade'] ) || !isset( $dados ['id_status'] )) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		try {
			$idAgenda = intval( $dados ['id_agenda_especialidade'] );
			$idStatus = intval( $dados ['id_status'] );
			$idObservacao = trim( $dados ['observacao'] );
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		$agenda_service = new AgendaEspecialidadeService();

		$agenda_service_response = $agenda_service->updateStatusAgendamentoEspecialidade( $idAgenda, $idStatus, $idObservacao );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A agenda foi cadastrada com sucesso.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Não foi possível cadastrar a agenda, pois foram detectados conflitos com horários já cadastrados.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function reagendarAgendamentoEspecialidadeByRecepcao() {

		$dados = $this->getDataPost();
		if (!isset( $dados ['id_agenda_antiga'] ) || !isset( $dados ['id_agenda_nova'] )) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		try {
			$idAgendaAntiga = intval( $dados ['id_agenda_antiga'] );
			$idAgendaNova = intval( $dados ['id_agenda_nova'] );
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		$agenda_service = new AgendaEspecialidadeService();

		$agenda_service_response = $agenda_service->reagendarAgendamentoEspecialidadeByRecepcao( $idAgendaAntiga, $idAgendaNova );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'O agendamento foi remarcado com sucesso.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Não foi possível remarcar, pois foram detectados conflitos com horários já cadastrados.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $agenda_service_response, $response_messages );

	}

	public function desmarcarAgendamentoEspecialidadeByRecepcao() {

		$dados = $this->getDataPost();
		if (!isset( $dados ['id_agenda'] )) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		try {
			$idAgenda = intval( $dados ['id_agenda'] );
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.'
			] );
		}

		$sql = <<<SQL
		    delete from agendamento_especialidade where id_agenda_especialidade = :id:
		SQL;
		$data = db_connect()->query( $sql, [ 
			'id' => $idAgenda
		] )
			->getResultArray();
		return $this->response->setStatusCode( 200 )
			->setJSON( [ 
			'message' => 'Desmarcado com sucesso com sucesso.'
		] );

	}

	public function getAgendaEspecialidadeByDate(): Response {

		if (!$this->validate( AgendaEspecialidadeValidation::getAgendaEspecialidadeDate() )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}

		$pagination = $this->getPaginationFromRequest();
		$query_filter_collection = new QueryFilterCollection( $_GET, QueryFilterTranslator::agenda_date() );
		$query_order_collection = new QueryOrderCollection( $_GET, QueryOrderTranslator::agenda_date() );
		$erro_service_response = (new AgendaEspecialidadeService())->getAgendaByDate( $pagination, $query_filter_collection, $query_order_collection,
			$_GET ['id_procedimento'], $_GET ['data_agenda'], $_GET ['id_unidade'] );
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados dos erros foram encontrados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'Nenhum registro foi encontrado.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $erro_service_response, $response_messages );

	}

}
