<?php

namespace App\DAO;

use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\Filter\QueryFilterBuilder;
use App\DAO\Order\QueryOrder;
use App\DAO\Pagination\Pagination;
use App\Entities\CEP\CEP;
use App\Entities\Cliente\Cliente;
use App\Entities\ConfirmacaoEmail\ConfirmacaoEmail;
use App\Entities\Endereco\Endereco;
use App\Entities\Paciente\Paciente;
use App\Entities\Pessoa\Pessoa;
use App\Entities\PessoaFisica\PessoaFisica;
use App\Entities\Usuario\Usuario;
use App\Entities\UsuarioPerfil\UsuarioPerfil;
use App\Mappers\PacienteMapper;
use App\Models\CEPModel;
use App\Models\ClienteModel;
use App\Models\ConfirmacaoEmailModel;
use App\Models\EnderecoModel;
use App\Models\PacienteModel;
use App\Models\PessoaFisicaModel;
use App\Models\PessoaModel;
use App\Models\UsuarioModel;
use App\Models\UsuarioPerfilModel;
use App\Services\LogService;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\Paciente\PacienteUpdateViewModel\PacienteUpdateViewModel;
use App\ViewModels\Paciente\PacienteRegistrationViewModel\PacienteRegistrationViewModel;
use Exception;
use Kint\Parser\DOMDocumentPlugin;

class PacienteDAO extends DAO {

	public function persistPacienteRegistrationVM(PacienteRegistrationViewModel $paciente_registration_vm, callable $send_email): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$this->db->transStart();
			$cep = $this->persistCepFromPacienteRegistrationVM( $paciente_registration_vm );
			$endereco = $this->persistEnderecoFromPacienteRegistrationVM( $paciente_registration_vm, $cep );
			$pessoa = $this->persistPessoaFromPacienteRegistrationVM( $paciente_registration_vm, $endereco );
			$usuario = $this->persistUsuarioFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$paciente = $this->persistPacienteFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$cliente = $this->persistClienteFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$pessoa_fisica = $this->persistPessoaFisicaFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$usuario_perfil = $this->persistUsuarioPerfilFromPacienteRegistrationVM( $paciente_registration_vm, $usuario );
			if ($paciente_registration_vm->getTokenConfirmacaoEmail()) {
				$confirmacao_email = $this->persistConfirmacaoEmailFromPacienteRegistrationVM( $paciente_registration_vm, $usuario );
			}
			$error = $this->db->error();
			if ($error && $error ['code']) {
				$this->setDatabaseErrorsForPacienteRegistration( $dao_response, $error );
			} else {
				$status_service_response_send_email = $send_email();
				if ($status_service_response_send_email === ServiceResponseInterface::SUCESS) {

					//
				} else {
					(new LogService())->log_error( $status_service_response_send_email, 'Falha no envio do email de confirmação de cadastro de um paciente.',
						$paciente_registration_vm->toArray() );
					// $dao_response->setStatus(DAOResponseInterface::INTERNAL_DAO_ERROR);
				}
			}

			$dao_response->setStatus( DAOResponseInterface::SUCESS );
			$this->db->transComplete();
			$dao_response->setData( $paciente );
		} catch ( Exception $exception ) {
			$this->setDatabaseErrorsForPacienteRegistration( $dao_response, $this->db->error() );
			$dao_response->setErrors( $this->db->error() );
		}

		return $dao_response;

	}

	public function persistPacienteSelfRegistrationVM(PacienteRegistrationViewModel $paciente_registration_vm, callable $send_email): DAOResponse {

		$dao_response = new DAOResponse();
		try {

			$this->db->transStart();
			$cep = $this->persistCepFromPacienteRegistrationVM( $paciente_registration_vm );
			$endereco = $this->persistEnderecoFromPacienteRegistrationVM( $paciente_registration_vm, $cep );
			$pessoa = $this->persistPessoaFromPacienteRegistrationVM( $paciente_registration_vm, $endereco );
			$usuario = $this->persistUsuarioFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$paciente = $this->persistPacienteFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$cliente = $this->persistClienteFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$pessoa_fisica = $this->persistPessoaFisicaFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
			$usuario_perfil = $this->persistUsuarioPerfilFromPacienteRegistrationVM( $paciente_registration_vm, $usuario );
			if ($paciente_registration_vm->getTokenConfirmacaoEmail()) {
				$confirmacao_email = $this->persistConfirmacaoEmailFromPacienteRegistrationVM( $paciente_registration_vm, $usuario );
			}
			$error = $this->db->error();
			if ($error && $error ['code']) {
				$this->setDatabaseErrorsForPacienteRegistration( $dao_response, $error );
			} else {
				$status_service_response_send_email = $send_email();
				if ($status_service_response_send_email === ServiceResponseInterface::SUCESS) {
					$dao_response->setStatus( DAOResponseInterface::SUCESS );
					$dao_response->setData( $paciente );
					$this->db->transComplete();
				} else {
					(new LogService())->log_error( $status_service_response_send_email, 'Falha no envio do email de confirmação de cadastro de um paciente.',
						$paciente_registration_vm->toArray() );
					$dao_response->setStatus( DAOResponseInterface::INTERNAL_DAO_ERROR );
				}

				$dao_response->setStatus( DAOResponseInterface::SUCESS );
				$dao_response->setData( $paciente );
				$this->db->transComplete();
			}
		} catch ( Exception $exception ) {
			$this->setDatabaseErrorsForPacienteRegistration( $dao_response, $this->db->error() );
			$dao_response->setErrors( $this->db->error() );
		}
		return $dao_response;

	}

	private function setDatabaseErrorsForPacienteRegistration(DAOResponse $dao_response, array $error): void {

		if ($error ['code']) {
			$dao_response->setStatus( $error ['code'] );
			$dao_response->setErrors( $this->getDatabaseResponseErrorsForPersistence( $error ) );
		} else {
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		}
		log_message( 'error', json_encode( $error ) );

	}

	private function persistEnderecoFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, CEP $cep): Endereco {

		$endereco_model = new EnderecoModel();
		$endereco = PacienteMapper::getEnderecoFromPacienteRegistrationVM( $paciente_registration_vm, $cep );
		$endereco_model->registerEndereco( $endereco );
		if (!$endereco->getId()) {
			throw new Exception( 'O cadastro de endereço não foi teve êxito' );
		}
		return $endereco;

	}

	private function persistPessoaFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, Endereco &$endereco): Pessoa {

		$pessoa_model = new PessoaModel();
		$pessoa = PacienteMapper::getPessoaFromPacienteRegistrationVM( $paciente_registration_vm, $endereco );
		$pessoa_model->registerPessoa( $pessoa );
		if (!$pessoa->getId()) {
			throw new Exception( 'O cadastro de pessoa não foi teve êxito' );
		}
		return $pessoa;

	}

	private function persistPessoaFisicaFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, Pessoa &$pessoa): PessoaFisica {

		$pessoa_fisica_model = new PessoaFisicaModel();
		$pessoa_fisica = PacienteMapper::getPessoaFisicaFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
		$pessoa_fisica_model->registerPessoaFisica( $pessoa_fisica );
		if (!$pessoa_fisica->getId()) {
			throw new Exception( 'O cadastro de pessoa_fisica não foi teve êxito' );
		}
		return $pessoa_fisica;

	}

	private function persistUsuarioFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, Pessoa &$pessoa): Usuario {

		$usuario_model = new UsuarioModel();
		$usuario = PacienteMapper::getUsuarioFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
		$usuario_model->registerUsuario( $usuario );
		if (!$usuario->getId()) {
			throw new Exception( 'O cadastro de usuario não foi teve êxito' );
		}
		return $usuario;

	}

	private function persistCepFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm): CEP {

		$cep = PacienteMapper::getCepFromPacienteRegistrationVM( $paciente_registration_vm );
		$cep_model = new CEPModel();
		// $cep_dao = new CEPDAO();
		// $cep = $cep_dao->getDatabaseCEP( $cep->getCep() );

		$cep_model->registerCep( $cep );
		if (!$cep->getCep()) {
			throw new Exception( 'O cadastro de cep não foi teve êxito' );
		}
		return $cep;

	}

	private function persistPacienteFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, Pessoa &$pessoa): Paciente {

		$paciente_model = new PacienteModel();
		$paciente = PacienteMapper::getPacienteFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
		$paciente_model->registerPaciente( $paciente );
		if (!$paciente->getId()) {
			throw new Exception( 'O cadastro de paciente não foi teve êxito' );
		}
		return $paciente;

	}

	private function persistClienteFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, Pessoa &$pessoa): Cliente {

		$cliente_model = new CLienteModel();
		$cliente = PacienteMapper::getClienteFromPacienteRegistrationVM( $paciente_registration_vm, $pessoa );
		$cliente_model->registerCliente( $cliente );
		if (!$cliente->getId()) {
			throw new Exception( 'O cadastro de cliente não foi teve êxito' );
		}
		return $cliente;

	}

	private function persistUsuarioPerfilFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, Usuario &$usuario): UsuarioPerfil {

		$usuario_perfil_model = new UsuarioPerfilModel();
		$usuario_perfil = PacienteMapper::getUsuarioPerfilFromPacienteRegistrationVM( $paciente_registration_vm, $usuario );
		$usuario_perfil_model->registerUsuarioPerfil( $usuario_perfil );
		if (!$usuario_perfil->getId()) {
			throw new Exception( 'O cadastro de usuario_perfil não foi teve êxito' );
		}
		return $usuario_perfil;

	}

	private function persistConfirmacaoEmailFromPacienteRegistrationVM(PacienteRegistrationViewModel &$paciente_registration_vm, Usuario &$usuario): ConfirmacaoEmail {

		$confirmacao_email_model = new ConfirmacaoEmailModel();
		$confirmacao_email = PacienteMapper::getConfirmacaoEmailFromPacienteRegistrationVM( $paciente_registration_vm, $usuario );
		$confirmacao_email_model->registerConfirmacaoEmail( $confirmacao_email );
		if (!$confirmacao_email->getId()) {
			throw new Exception( 'O cadastro de confirmacao_email não foi teve êxito' );
		}
		return $confirmacao_email;

	}

	public function getPacienteList(?Pagination $pagination, ?QueryFilterCollection $query_filter_collection,
			?QueryOrderCollection $query_order_collection = null): DAOResponse {

		$sql = <<<SQL
		       SELECT
		            paciente.id as id ,cliente.id as id_cliente
		            ,paciente.peso as peso ,paciente.altura as altura
		            ,pessoa_fisica.cpf as cpf ,pessoa_fisica.rg as rg
		            ,pessoa_fisica.nome as nome ,pessoa_fisica.genero as genero
		            ,pessoa_fisica.profissao as profissao
		            ,pessoa_fisica.estado_civil as estado_civil
		            ,SUBSTRING(pessoa_fisica.data_nascimento, 1, 10) AS data_nascimento
		            ,pessoa.telefone_1 as telefone_1, pessoa.telefone_2 as telefone_2, pessoa.telefone_3 as telefone_3
		            ,pessoa.observacao as observacao, endereco.numero as numero
		            ,endereco.complemento as complemento, endereco.referencias as referencias
		            ,usuario.foto as foto, cep.cep as cep, cep.estado as estado, cep.cidade as cidade
		            ,cep.bairro as bairro, cep.logradouro as logradouro
		            ,usuario.email as email, paciente.indicado_por as indicado_por
		            ,paciente.convenio as convenio
		        FROM cliente, paciente , usuario, endereco, pessoa, pessoa_fisica, cep, usuario_perfil 
		        where
		            usuario.ativo = 1
		            and usuario.id = usuario_perfil.id_usuario 
		            and usuario_perfil.id_perfil = 4
		            and cliente.id_pessoa = pessoa.id
		            and paciente.id_pessoa = pessoa.id
		            and pessoa_fisica.id_pessoa = pessoa.id
		            and usuario.id_pessoa = pessoa.id
		            and pessoa.id_endereco = endereco.id
		            and cep.id = endereco.cep
		SQL;
		$binds = [ ];
		return $this->getDAOResponseFromPaginatedSelect( $binds, $pagination, $query_filter_collection, $query_order_collection, $sql,
			function (array $result_array) {
				return PacienteMapper::getPacienteDetailsVMListFromArray( $result_array );
			} );

	}

	public function getPaciente(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = '
            SELECT
                paciente.id as id,
                paciente.peso as peso,
                paciente.altura as altura,
                cliente.id as id_cliente,
                pessoa_fisica.cpf as cpf,
                pessoa_fisica.rg as rg,
                pessoa_fisica.nome as nome,
                pessoa_fisica.genero as genero,
                pessoa_fisica.profissao as profissao,
                pessoa_fisica.estado_civil as estado_civil,
                SUBSTRING(pessoa_fisica.data_nascimento, 1, 10) AS data_nascimento,
                pessoa.telefone_1 as telefone_1,
                pessoa.telefone_2 as telefone_2,
                pessoa.telefone_3 as telefone_3,
                cep.cep as cep,
                endereco.numero as numero,
                endereco.complemento as complemento,
                endereco.referencias as referencias,
                cep.estado as estado,
                cep.cidade as cidade,
                cep.bairro as bairro,
                cep.logradouro as logradouro,
                usuario.email as email,
                usuario.foto as foto,
                paciente.indicado_por as indicado_por,
                paciente.convenio as convenio
            FROM paciente
            INNER JOIN pessoa ON paciente.id_pessoa = pessoa.id 
           	INNER JOIN pessoa_fisica ON pessoa_fisica.id_pessoa = pessoa.id
           	INNER JOIN usuario ON usuario.id_pessoa = pessoa.id
           	INNER JOIN endereco ON pessoa.id_endereco = endereco.id
           	INNER JOIN cep ON cep.id = endereco.cep 
            LEFT JOIN cliente ON cliente.id_pessoa = pessoa.id
            WHERE 
            	usuario.ativo = 1
            LIMIT 1
        ';
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
			function (array $result_array) {
				$pacienteVM = PacienteMapper::getPacienteDetailsVMFromArray( $result_array [0] );
				return $pacienteVM;
			} );

	}

	public function getPacienteFromId(int $id_paciente) {

		$sql = "  SELECT * FROM paciente WHERE paciente.id=? ";

		$binds = [ 
			$id_paciente
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();

		return ($result_array);

	}

	public function getImagePaciente(int $id_paciente) {

		$sql = '
            SELECT
                usuario.foto
            FROM paciente
            INNER JOIN pessoa ON paciente.id_pessoa = pessoa.id 
           	INNER JOIN pessoa_fisica ON pessoa_fisica.id_pessoa = pessoa.id
           	INNER JOIN usuario ON usuario.id_pessoa = pessoa.id
           	INNER JOIN endereco ON pessoa.id_endereco = endereco.id
           	INNER JOIN cep ON cep.id = endereco.cep 
            LEFT JOIN cliente ON paciente.id_pessoa = pessoa.id
            WHERE 
            	usuario.ativo = 1 AND paciente.id = :id_paciente:
            LIMIT 1
        ';
		$binds = [ 
			'id_paciente' => $id_paciente
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return (($result_array [0] ['foto']));

	}

	public function getPetsPaciente(int $id_paciente) {

		$sql = '
            select * from paciente p
               inner join cliente c on p.id_pessoa = c.id_pessoa
               inner join pet_cliente pc on pc.id_cliente = c.id
               inner join pet on pet.id = pc.id_pet
               where p.id = :id_paciente:
        ';
		$binds = [ 
			'id_paciente' => $id_paciente
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return $result_array;

	}

	public function persistPacienteUpdateVM(int $id_paciente, PacienteUpdateViewModel $paciente_update_vm): DAOResponse {

		$dao_response = new DAOResponse();

		$this->db->transStart();

		$status_persistence = $this->persistCepFromPacienteUpdateVM( $id_paciente, $paciente_update_vm );
		$status_persistence = $this->persistEnderecoFromPacienteUpdateVM( $id_paciente, $paciente_update_vm );
		$status_persistence = $status_persistence && $this->persistPessoaFromPacienteUpdateVM( $id_paciente, $paciente_update_vm );
		$status_persistence = $status_persistence && $this->persistUsuarioFromPacienteUpdateVM( $id_paciente, $paciente_update_vm );
		$status_persistence = $status_persistence && $this->persistPacienteFromPacienteUpdateVM( $id_paciente, $paciente_update_vm );
		$status_persistence = $status_persistence && $this->persistPessoaFisicaFromPacienteUpdateVM( $id_paciente, $paciente_update_vm );

		$error = $this->db->error();

		if ($error && $error ['code']) {
			$this->setDatabaseErrorsForPacienteUpdate( $dao_response, $error );
			$dao_response->setErrors( $error );
			return $dao_response;
		} else if ($status_persistence) {
			$this->db->transComplete();
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
		}
		$this->db->close();
		return $dao_response;

	}

	private function setDatabaseErrorsForPacienteUpdate(DAOResponse $dao_response, array $error): void {

		$dao_response->setStatus( $error ['code'] );
		$dao_response->setErrors( $this->getDatabaseResponseErrorsForPersistence( $error ) );

	}

	private function persistCepFromPacienteUpdateVM(int $id_paciente, PacienteUpdateViewModel &$paciente_update_vm): bool {

		$cep_model = new CEPModel();
		$cep = PacienteMapper::getCepFromPacienteUpdateVM( $paciente_update_vm );
		$sucess_update = $cep_model->updateCepByPacienteID( $id_paciente, $cep );
		return $sucess_update;

	}

	private function persistEnderecoFromPacienteUpdateVM(int $id_paciente, PacienteUpdateViewModel &$paciente_update_vm): bool {

		$endereco_model = new EnderecoModel();
		$endereco = PacienteMapper::getEnderecoFromPacienteUpdateVM( $paciente_update_vm );
		$sucess_update = $endereco_model->updateEnderecoByPacienteID( $id_paciente, $endereco );
		return $sucess_update;

	}

	private function persistPessoaFromPacienteUpdateVM(int $id_paciente, PacienteUpdateViewModel &$paciente_update_vm): bool {

		$pessoa_model = new PessoaModel();
		$pessoa = PacienteMapper::getPessoaFromPacienteUpdateVM( $paciente_update_vm );
		$sucess_update = $pessoa_model->updatePessoaByPacienteID( $id_paciente, $pessoa );
		return $sucess_update;

	}

	private function persistPessoaFisicaFromPacienteUpdateVM(int $id_paciente, PacienteUpdateViewModel &$paciente_update_vm): bool {

		$pessoa_fisica_model = new PessoaFisicaModel();
		$pessoa_fisica = PacienteMapper::getPessoaFisicaFromPacienteUpdateVM( $paciente_update_vm );
		$sucess_update = $pessoa_fisica_model->updatePessoaFisicaByPacienteID( $id_paciente, $pessoa_fisica );

		return $sucess_update;

	}

	private function persistUsuarioFromPacienteUpdateVM(int $id_paciente, PacienteUpdateViewModel &$paciente_update_vm): bool {

		$usuario_model = new UsuarioModel();
		$usuario = PacienteMapper::getUsuarioFromPacienteUpdateVM( $paciente_update_vm );
		$sucess_update = $usuario_model->updateUsuarioByPacienteID( $id_paciente, $usuario );
		return $sucess_update;

	}

	private function persistPacienteFromPacienteUpdateVM(int $id_paciente, PacienteUpdateViewModel &$paciente_update_vm): bool {

		$paciente_model = new PacienteModel();
		$paciente = PacienteMapper::getPacienteFromPacienteUpdateVM( $paciente_update_vm );
		$sucess_update = $paciente_model->updatePacienteByID( $id_paciente, $paciente );
		return $sucess_update;

	}

	private function getDatabaseResponseErrorsForPersistence(array $error): array {

		$dao_response_errors = [ ];
		if ($error && $error ['code']) {
			if ($error ['code'] === DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS) {
				if (strpos( $error ['message'], 'cep' ) !== false) {
					$dao_response_errors ['cep'] = 'Esse CEP não existe.';
				}
			} else if ($error ['code'] === DAOResponseInterface::DUPLICATED_UNIQUE_KEY) {
				if (strpos( $error ['message'], '\'cpf\'' ) !== false) {
					$dao_response_errors ['cpf'] = 'Uma pessoa com esse CPF já está cadastrada no sistema.';
				}
				if (strpos( $error ['message'], '\'pessoa_fisica.rg\'' ) !== false) {
					$dao_response_errors ['rg'] = 'Uma pessoa com esse RG já está cadastrada no sistema.';
				}
				if (strpos( $error ['message'], '\'email\'' ) !== false) {
					$dao_response_errors ['email'] = 'Uma pessoa com esse email já está cadastrada no sistema.';
				}
			}
		}
		return $dao_response_errors;

	}

	# -----------------------------------------------------------------------------------------------------------#
	public function persistPacienteUpdateObservacaoVM(int $id_paciente, PacienteUpdateViewModel $paciente_update_vm): DAOResponse {

		$dao_response = new DAOResponse();
		$this->db->transStart();
		$status_persistence = $this->persistPessoaFromPacienteUpdateVM( $id_paciente, $paciente_update_vm );
		$error = $this->db->error();
		if ($error && $error ['code']) {
			$this->setDatabaseErrorsForPacienteUpdate( $dao_response, $error );
			$dao_response->setErrors( $error );
			return $dao_response;
		} else if ($status_persistence) {
			$this->db->transComplete();
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
		}
		$this->db->close();
		return $dao_response;

	}

	public function getPacienteIDFromUsuarioID(int $id_usuario): int {

		$sql = '
            SELECT
                paciente.id as id_paciente
            FROM
                paciente, pessoa, usuario
            WHERE
                paciente.id_pessoa  = pessoa.id AND
                usuario.id_pessoa  = pessoa.id AND usuario.id = :id_usuario:
            LIMIT 1
        ';
		$binds = [ 
			'id_usuario' => $id_usuario
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		if (count( $result_array ) > 0) {
			return $result_array [0] ['id_paciente'];
		}
		return 0;

	}

	public function getDadosPacienteByIdPaciente(int $id_paciente): DAOResponse {

		$dao_response = new DAOResponse();
		$sql = <<<SQL
			select
				c.id as id_cliente , pc.id as id_paciente , p.id as id_pessoa,
				pf.nome , pf.cpf , pf.rg , pf.data_nascimento , pf.genero , 
				cep.cidade , cep.estado , cep.bairro , ed.numero , ed.complemento ,
				ed.referencias,	cep.logradouro ,cep.cep ,p.telefone_1 , p.telefone_2 ,
				p.telefone_3, p.observacao, u.email 
			from 
				paciente pc , cliente c , pessoa p, pessoa_fisica pf , endereco ed, 
				cep, usuario u, usuario_perfil up  
			where
				pc.id = :id_paciente: and pc.id_pessoa = p.id  
				and pc.id_pessoa = u.id_pessoa 
				and u.id = up.id_usuario 
				and up.id_perfil = 4
				and c.id_pessoa = p.id and pf.id_pessoa = p.id
				and p.id_endereco = ed.id and ed.cep = cep.id
		SQL;

		$binds = [ 
			'id_paciente' => $id_paciente
		];

		$conn = db_connect();
		$resp = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
			return $dao_response;
		}
		$dao_response->setStatus( DAOResponseInterface::SUCESS );
		$dao_response->setData( $resp [0] );
		return $dao_response;

	}

	public function getDadosPacienteByIdCliente(int $id_cliente): DAOResponse {

		$dao_response = new DAOResponse();
		$sql = <<<SQL
			select
				c.id as id_cliente , pc.id as id_paciente , p.id as id_pessoa,
				pf.nome , pf.cpf , pf.rg , pf.data_nascimento , pf.genero , 
				cep.cidade , cep.estado , cep.bairro , ed.numero , ed.complemento ,
				ed.referencias,	cep.logradouro ,cep.cep ,p.telefone_1 , p.telefone_2 ,
				p.telefone_3, p.observacao, u.email 
			from
				paciente pc , cliente c , pessoa p, pessoa_fisica pf , endereco ed, cep,
				usuario u, usuario_perfil up 
			where
				c.id = :id_cliente: and c.id_pessoa = p.id
				and c.id_pessoa =pc.id_pessoa 
				and c.id_pessoa = u.id_pessoa
				and u.id = up.id_usuario 
				and up.id_perfil = 4
				and pf.id_pessoa = p.id
				and p.id_endereco = ed.id 
				and ed.cep = cep.id
		SQL;

		$binds = [ 
			'id_cliente' => $id_cliente
		];

		$conn = db_connect();
		$resp = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
			return $dao_response;
		}
		$dao_response->setStatus( DAOResponseInterface::SUCESS );
		$dao_response->setData( $resp [0] );
		return $dao_response;

	}

	public function getClienteIdByPacienteId(int $idPaciente): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			select p.id as paciente_id, p.id_pessoa as pessoa_id,c.id as cliente_id
			from paciente p, cliente c
			where
				p.id = :paciente_id:
				and p.id_pessoa =c.id_pessoa 
		SQL;
		$binds = [ 
			'paciente_id' => $idPaciente
		];

		$conn = db_connect();
		$resp = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
			return $dao_response;
		}
		if (count( $resp ) == 0) {
			$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
			return $dao_response;
		}
		$dao_response->setStatus( DAOResponseInterface::SUCESS );
		$dao_response->setData( [ 
			'cliente_id' => $resp [0] ['cliente_id']
		] );
		return $dao_response;

	}

	public function setClienteAceiteTermo(int $idcliente): DAOResponse {

		$sql = <<<SQL
			update cliente
			set aceite_termo = 1
			where  id  = :cliente_id:
		SQL;

		$binds = [ 
			'cliente_id' => $idcliente
		];

		$daoResponse = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )->numRows;
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$daoResponse->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$daoResponse->setErrors( $errors );
			$daoResponse->setData( [ ] );
		} else {
			$affectrows = $conn->affectedRows();
			if ($affectrows == 0) {
				$daoResponse->setStatus( DAOResponseInterface::INSUFFICIENT_DATA );
				$daoResponse->setData( [ ] );
			} else {
				$daoResponse->setStatus( DAOResponseInterface::SUCESS );
				$daoResponse->setData( [ ] );
			}
		}

		return $daoResponse;

	}

	public function getAceitermoStatusByClienteId(int $idcliente): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			select 
				c.aceite_termo 
			from  cliente c
			where
				c.id = :cliente_id:
				
		SQL;
		$binds = [ 
			'cliente_id' => $idcliente
		];

		$conn = db_connect();
		$resp = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
			return $dao_response;
		}
		if (count( $resp ) == 0) {
			$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
			return $dao_response;
		}
		$dao_response->setStatus( DAOResponseInterface::SUCESS );
		$dao_response->setData( $resp );

		return $dao_response;

	}

}
