<?php

namespace App\Controllers;

use App\DAO\PacienteDAO;
use App\DAO\Filter\QueryFilter;
use App\DAO\Filter\QueryFilterTranslator;
use App\DAO\Order\QueryOrderTranslator;
use App\Services\ClienteService;
use App\Services\PacienteService;
use App\Services\JWT\UsuarioLogado;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\Validations\PacienteValidation;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;


class PacienteController extends BaseController {

	public function register(): Response {

		if (!$this->validate( PacienteValidation::register() )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$data_post = $_POST;
		if (!$data_post ['complemento']) {
			$data_post ['complemento'] = '';
		}
		if (!$data_post ['referencias']) {
			$data_post ['referencias'] = '';
		}
		$paciente_service_response = (new PacienteService())->registerPaciente( $data_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' => 'O paciente foi cadastrado com sucesso.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'errors' => $paciente_service_response->getErrors(),
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $paciente_service_response, $response_messages );

	}

	public function selfRegister(): Response {

		if (!$this->validate( PacienteValidation::selfRegister() )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$data_post = $_POST;
		if (!$data_post ['complemento']) {
			$data_post ['complemento'] = '';
		}
		if (!$data_post ['referencias']) {
			$data_post ['referencias'] = '';
		}

		$paciente_service = new PacienteService();
		$paciente_service_response = $paciente_service->selfRegisterPaciente( $data_post );

		if ($paciente_service_response->getStatus() == ServiceResponseInterface::SUCESS) {
			$dados = $paciente_service_response->getData();
			$paciente_service->setClienteAceiteTermo( $dados ['id_cliente'] );
		}

		$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 Tutor foi cadastrado com sucesso.'
			],
			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( $paciente_service_response, $response_messages );

	}

	public function getPacienteByID(int $id_paciente): Response {

		$service = new PacienteService();
		$service_response = $service->getDadosPacienteByIdPaciente( $id_paciente );

		$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' => ' '
			],
			ServiceResponseInterface::UNKNOWN_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $service_response, $response_messages );

		// $query_filter = QueryFilter::builder()->setNameParam( 'id' )->setTable( 'paciente' )->setValue( $id_paciente )->setIsExact( true )->build();
		// return $this->getPaciente( $query_filter );
	}

	public function getPacienteByIdCliente(int $id_cliente): Response {

		$service = new PacienteService();
		$service_response = $service->getDadosPacienteByIdCiente( $id_cliente );

		$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' => ' '
			],
			ServiceResponseInterface::UNKNOWN_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $service_response, $response_messages );

		// $query_filter = QueryFilter::builder()->setNameParam( 'id' )->setTable( 'paciente' )->setValue( $id_paciente )->setIsExact( true )->build();
		// return $this->getPaciente( $query_filter );
	}

	public function getPacienteByUsuarioID(int $id_usuario): Response {

		$query_filter = QueryFilter::builder()->setNameParam( 'id' )
			->setTable( 'usuario' )
			->setValue( $id_usuario )
			->setIsExact( true )
			->build();
		return $this->getPaciente( $query_filter );

	}

	public function getPacienteList(): Response {

		$pagination = $this->getPaginationFromRequest();

		if ($_GET ['sort'] === null) {
			$_GET ['sort'] = "nome";
		}

		$profileId = UsuarioLogado::getProfileId();
		$filters = $_GET;
		if ($profileId === 4) // cliente
		{
			$filters ['id_usuario'] = UsuarioLogado::getUsuarioId();
		} else {
			unset( $filters ['id_usuario'] );
		}

		$query_filter_collection = new QueryFilterCollection( $filters, QueryFilterTranslator::paciente() );
		$query_order_collection = new QueryOrderCollection( $_GET, QueryOrderTranslator::paciente() );
		$paciente_service_response = (new PacienteService())->getPacienteList( $pagination, $query_filter_collection, $query_order_collection );
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados dos pacientes 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( $paciente_service_response, $response_messages );

	}

	private function getPaciente(QueryFilter $query_filter): Response {

		$paciente_service_response = (new PacienteService())->getPaciente( $query_filter );
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados do paciente 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( $paciente_service_response, $response_messages );

	}

	public function updatePacienteData(int $id_paciente): Response {

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

		$paciente_dao = new PacienteDAO();
		$validation = $paciente_dao->getPacienteFromId( $id_paciente );

		if ($validation == null) {
			return $this->response->setJSON( [ 
				'message' => 'O paciente não está registrado.',
				'errors' => $this->validation->getErrors()
			] );
		}

		if (isset( $_POST ["altura"] )) {
			$_POST ["altura"] = ( float ) str_replace( ",", ".", $_POST ["altura"] );
		}

		if (isset( $_POST ["peso"] )) {
			$_POST ["peso"] = ( float ) str_replace( ",", ".", $_POST ["peso"] );
		}

		$paciente_service_response = (new PacienteService())->updatePacienteData( $id_paciente, $_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' => 'Os dados do paciente foram atualizados com sucesso.'
			],
			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( $paciente_service_response, $response_messages );

	}

	public function updatePacienteObservacao(int $id_paciente): Response {

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

		$paciente_service_response = (new PacienteService())->updatePacienteObservacao( $id_paciente, $_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' => 'Os dados do paciente foram atualizados com sucesso.'
			],
			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( $paciente_service_response, $response_messages );

	}

	public function getAceitermoStatusByClienteId(int $idcliente): Response {

		$paciente_service = new PacienteService();
		$paciente_service_response = $paciente_service->getAceitermoStatusByClienteId( $idcliente );
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados do paciente 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( $paciente_service_response, $response_messages );

	}

	public function setAceitoTermos(): Response {

		$cliente_service = new ClienteService();
		$paciente_service_response = $cliente_service->setAceitoTermos();
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados do paciente 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( $paciente_service_response, $response_messages );

	}

}
