<?php

namespace App\DAO;

use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Pagination\Pagination;
use App\Entities\AssistenteMedico\AssistenteMedico;
use App\Entities\CEP\CEP;
use App\Entities\Cliente\Cliente;
use App\Entities\ConfirmacaoEmail\ConfirmacaoEmail;
use App\Entities\Endereco\Endereco;
use App\Entities\Assistente\Assistente;
use App\Entities\Paciente\Paciente;
use App\Entities\Pessoa\Pessoa;
use App\Entities\PessoaFisica\PessoaFisica;
use App\Entities\Profissional\Profissional;
use App\Entities\ProfissionalClinica\ProfissionalClinica;
use App\Entities\Usuario\Usuario;
use App\Entities\UsuarioPerfil\UsuarioPerfil;
use App\Mappers\AssistenteMapper;
use App\Models\AssistenteMedicoModel;
use App\Models\CEPModel;
use App\Models\ClienteModel;
use App\Models\ConfirmacaoEmailModel;
use App\Models\EnderecoModel;
use App\Models\AssistenteModel;
use App\Models\PacienteModel;
use App\Models\PessoaFisicaModel;
use App\Models\PessoaModel;
use App\Models\ProfissionalClinicaModel;
use App\Models\ProfissionalModel;
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\Assistente\AssistenteRegistrationViewModel\AssistenteRegistrationViewModel;
use App\ViewModels\Assistente\AssistenteUpdateViewModel\AssistenteUpdateViewModel;
use Exception;

class AssistenteDAO extends DAO {

	public function persistAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, callable $send_email): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$this->db->transStart();
			$cep = $this->persistCepFromAssistenteRegistrationVM( $assistente_registration_vm );
			$endereco = $this->persistEnderecoFromAssistenteRegistrationVM( $assistente_registration_vm, $cep );
			$pessoa = $this->persistPessoaFromAssistenteRegistrationVM( $assistente_registration_vm, $endereco );
			$usuario = $this->persistUsuarioFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
			$paciente = $this->persistPacienteFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
			# $cliente = $this->persistClienteFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
			$pessoa_fisica = $this->persistPessoaFisicaFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
			$usuario_perfil = $this->persistUsuarioPerfilFromAssistenteRegistrationVM( $assistente_registration_vm, $usuario );
			$profissional = $this->persistProfissionalFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
			// log_message( 'error', "Oi" );
			$profissional_clinica = $this->persistProfissionalClinicaFromAssistenteRegistrationVM( $assistente_registration_vm, $profissional );
			// log_message( 'error', "Oi" );
			$assistente = $this->persistAssistenteFromAssistenteRegistrationVM( $assistente_registration_vm, $profissional );
			// $asssitente_medico = $this->persistAssistenteMedicoFromAssistenteRegistrationVM( $assistente_registration_vm, $assistente );
			// if ($assistente_registration_vm->getTokenConfirmacaoEmail()) {
			// $confirmacao_email = $this->persistConfirmacaoEmailFromAssistenteRegistrationVM( $assistente_registration_vm, $usuario );
			// }

			$error = $this->db->error();
			if ($error && $error ['code']) {
				$this->setDatabaseErrorsForAssistenteRegistration( $dao_response, $error );
			} else {
				// $status_service_response_send_email = $send_email();
				$status_service_response_send_email = ServiceResponseInterface::SUCESS;
				if ($status_service_response_send_email === ServiceResponseInterface::SUCESS) {
					$dao_response->setStatus( DAOResponseInterface::SUCESS );
					$dao_response->setData( $assistente );
					$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 assistente.',
						$assistente_registration_vm->toArray() );
					$dao_response->setStatus( DAOResponseInterface::INTERNAL_DAO_ERROR );
				}
			}
		} catch ( Exception $exception ) {
			$this->setDatabaseErrorsForAssistenteRegistration( $dao_response, $this->db->error() );
		}
		return $dao_response;

	}

	private function setDatabaseErrorsForAssistenteRegistration(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 persistCepFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm): CEP {

		$cep_model = new CEPModel();
		$cep = AssistenteMapper::getCepFromAssistenteRegistrationVM( $assistente_registration_vm );
		$cep_model->registerCep( $cep );
		if (!$cep->getId()) {
			throw new Exception( 'O cadastro de cep não foi teve êxito' );
		}
		return $cep;

	}

	private function persistEnderecoFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, CEP $cep): Endereco {

		$endereco_model = new EnderecoModel();
		$endereco = AssistenteMapper::getEnderecoFromAssistenteRegistrationVM( $assistente_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 persistPessoaFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Endereco &$endereco): Pessoa {

		$pessoa_model = new PessoaModel();
		$pessoa = AssistenteMapper::getPessoaFromAssistenteRegistrationVM( $assistente_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 persistPessoaFisicaFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Pessoa &$pessoa): PessoaFisica {

		$pessoa_fisica_model = new PessoaFisicaModel();
		$pessoa_fisica = AssistenteMapper::getPessoaFisicaFromAssistenteRegistrationVM( $assistente_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 persistUsuarioFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Pessoa &$pessoa): Usuario {

		$usuario_model = new UsuarioModel();
		$usuario = AssistenteMapper::getUsuarioFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
		$usuario_model->registerUsuario( $usuario );
		if (!$usuario->getId()) {
			throw new Exception( 'O cadastro de usuário não foi teve êxito' );
		}
		return $usuario;

	}

	private function persistPacienteFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$paciente_registration_vm, Pessoa &$pessoa): Paciente {

		$paciente_model = new PacienteModel();
		$paciente = AssistenteMapper::getPacienteFromAssistenteRegistrationVM( $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 persistClienteFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Pessoa &$pessoa): Cliente {

		$cliente_model = new CLienteModel();
		$cliente = AssistenteMapper::getClienteFromAssistenteRegistrationVM( $assistente_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 persistUsuarioPerfilFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Usuario &$usuario): UsuarioPerfil {

		$usuario_perfil_model = new UsuarioPerfilModel();
		$usuario_perfil = AssistenteMapper::getUsuarioPerfilFromAssistenteRegistrationVM( $assistente_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 persistConfirmacaoEmailFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Usuario &$usuario): ConfirmacaoEmail {

		$confirmacao_email_model = new ConfirmacaoEmailModel();
		$confirmacao_email = AssistenteMapper::getConfirmacaoEmailFromAssistenteRegistrationVM( $assistente_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;

	}

	private function persistProfissionalFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Pessoa &$pessoa): Profissional {

		$profissional_model = new ProfissionalModel();
		$profissional = AssistenteMapper::getProfissionalFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
		$profissional_model->registerProfissional( $profissional );
		if (!$profissional->getId()) {
			throw new Exception( 'O cadastro de profissional não foi teve êxito' );
		}
		return $profissional;

	}

	private function persistProfissionalClinicaFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Profissional &$pessoa): ProfissionalClinica {

		$profissional_clinica_model = new ProfissionalClinicaModel();

		foreach ( $assistente_registration_vm->getUnidades() as $value ) {
			if (strlen( trim( $value ) ) > 0) {
				$profissional_clinica = new ProfissionalClinica();
				$profissional_clinica->setIdPROFISSIONAL( $pessoa->getId() );
				$profissional_clinica->setIdPessoaJuridica( $value );
				$profissional_clinica_model->registerProfissionalClinica( $profissional_clinica );
			}
		}

		if (!$profissional_clinica->getId()) {
			throw new Exception( 'O cadastro de assistente_clinica não foi teve êxito' );
		}
		return $profissional_clinica;

	}

	private function persistAssistenteFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Profissional &$pessoa): Assistente {

		$assistente_model = new AssistenteModel();
		$assistente = AssistenteMapper::getAssistenteFromAssistenteRegistrationVM( $assistente_registration_vm, $pessoa );
		$assistente_model->registerAssistente( $assistente );
		if (!$assistente->getId()) {
			throw new Exception( 'O cadastro de assistente não teve êxito' );
		}
		return $assistente;

	}

	private function persistAssistenteMedicoFromAssistenteRegistrationVM(AssistenteRegistrationViewModel &$assistente_registration_vm, Assistente &$pessoa): AssistenteMedico {

		$assistente_medico_model = new AssistenteMedicoModel();
		foreach ( $assistente_registration_vm->getIdMedico() as $value ) :
			$assistente_medico = AssistenteMapper::getAssistenteMedicoFromAssistenteRegistrationVM( $value, $pessoa->getId() );
			$assistente_medico_model->registerAssistenteMedico( $assistente_medico );
			if (!$assistente_medico->getId()) {
				throw new Exception( 'O cadastro de assistente_medico não foi teve êxito' );
			}
		endforeach
		;
		return $assistente_medico;

	}

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

		$sql = <<<SQL
			SELECT
				assistente.id as id, 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,
				cep.cep as cep, cep.estado as estado, cep.cidade as cidade, 
				cep.bairro as bairro, cep.logradouro as logradouro,
				endereco.numero as numero, endereco.complemento as complemento,
				endereco.referencias as referencias, usuario.email as email, 
				usuario.ativo as ativo, usuario_status.descricao as ativo_desc,
				usuario.foto as foto, perfil.id as perfil_id, perfil.descricao as perfil_descricao
			FROM 
				perfil, pessoa , pessoa_fisica, usuario ,usuario_status, usuario_perfil,
				profissional , assistente , endereco, cep
			WHERE
				perfil.id = 3
				AND pessoa.id = pessoa_fisica.id_pessoa
				AND usuario.id_pessoa = pessoa.id
				AND usuario.ativo = usuario_status.id
				AND profissional.id_pessoa = pessoa.id
				AND usuario_perfil.id_usuario = usuario.id
				AND profissional.id = assistente.id_profissional
				AND pessoa.id_endereco = endereco.id
				AND perfil.id = usuario_perfil.id_perfil
				AND cep.id = endereco.cep
		SQL;
		$binds = [ ];
		return $this->getDAOResponseFromPaginatedSelect( $binds, $pagination, $query_filter_collection, $query_order_collection, $sql,
			function (array $result_array) {
				return AssistenteMapper::getAssistenteDetailsVMListFromArray( $result_array );
			} );

	}

	public function getAssistente(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = <<<SQL
			SELECT
				assistente.id as id, 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,
				cep.cep as cep, cep.estado as estado, cep.cidade as cidade,
				cep.bairro as bairro, cep.logradouro as logradouro,
				endereco.numero as numero, endereco.complemento as complemento,
				endereco.referencias as referencias, usuario.email as email,
				usuario.ativo as ativo, usuario_status.descricao as ativo_desc,
				usuario.foto as foto, perfil.id as perfil_id, perfil.descricao as perfil_descricao
			FROM
				perfil, pessoa , pessoa_fisica, usuario ,usuario_status, usuario_perfil,
				profissional , assistente , endereco, cep
			WHERE
				perfil.id = 3
				AND pessoa.id = pessoa_fisica.id_pessoa
				AND usuario.id_pessoa = pessoa.id
				AND usuario.ativo = usuario_status.id
				AND profissional.id_pessoa = pessoa.id
				AND usuario_perfil.id_usuario = usuario.id
				AND profissional.id = assistente.id_profissional
				AND pessoa.id_endereco = endereco.id
				AND perfil.id = usuario_perfil.id_perfil
				AND cep.id = endereco.cep
		SQL;
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
			function (array $result_array) {
				return AssistenteMapper::getAssistenteDetailsVMFromArray( $result_array [0] );
			} );

	}

	public function getMedicosFromAssistenteList(int $id_assistente) {

		$sql = '
            SELECT 
            medico.id as id_medico,   
            pessoa_fisica.nome
            FROM 
                assistente_medico, medico, profissional, pessoa_fisica 
                WHERE 
            	assistente_medico.id_medico = medico.id AND
            	medico.id_profissional = profissional.id AND
				profissional.id_pessoa = pessoa_fisica.id_pessoa AND
            	assistente_medico.id_assistente = :id_assistente:
        ';
		$binds = [ 
			'id_assistente' => $id_assistente
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return $result_array;

	}

	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'], '\'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 verifyAssistenteAndMedicoAreLinked(int $id_medico, int $assistente_uid): DAOResponse {

		$sql = '
            SELECT
                1
            FROM assistente_medico, assistente, profissional, usuario
            WHERE 
                assistente_medico.id_assistente = assistente.id AND
                profissional.id = assistente.id_profissional AND
                usuario.id_pessoa = profissional.id_pessoa AND
                usuario.id = :assistente_uid: AND
                id_medico = :id_medico:
            LIMIT 1
        ';
		$binds = [ 
			'id_medico' => $id_medico,
			'assistente_uid' => $assistente_uid
		];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, null, $sql, function (array $result_array): bool {
			return true;
		} );

	}

	public function persistAssistenteUpdateVM(int $id_paciente, AssistenteUpdateViewModel $assistente_update_vm): DAOResponse {

		$dao_response = new DAOResponse();
		$this->db->transStart();
		$status_persistence = $this->persistCepFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		$status_persistence = $this->persistEnderecoFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		$status_persistence = $status_persistence && $this->persistPessoaFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		$status_persistence = $status_persistence && $this->persistUsuarioFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		$status_persistence = $status_persistence && $this->persistUsuarioPerfilFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		$status_persistence = $status_persistence && $this->persistPacienteFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		$status_persistence = $status_persistence && $this->persistPessoaFisicaFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		// $status_persistence = $status_persistence && $this->persistAssistenteMedicoFromAssistenteUpdateVM( $id_paciente, $assistente_update_vm );
		$error = $this->db->error();
		if ($error && $error ['code']) {
			$this->setDatabaseErrorsForAssistenteUpdate( $dao_response, $error );
			return $dao_response;
		} else if ($status_persistence) {
			$this->db->transComplete();
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
		}
		$this->db->close();
		return $dao_response;

	}

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

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

	}

	private function persistCepFromAssistenteUpdateVM(int $id_paciente, AssistenteUpdateViewModel &$paciente_update_vm): bool {

		$cep_model = new CEPModel();
		$cep = AssistenteMapper::getCepFromAssistenteUpdateVM( $paciente_update_vm );
		$sucess_update = $cep_model->updateCepByAssistenteID( $id_paciente, $cep );
		return $sucess_update;

	}

	private function persistEnderecoFromAssistenteUpdateVM(int $id_paciente, AssistenteUpdateViewModel &$assistente_update_vm): bool {

		$endereco_model = new EnderecoModel();
		$endereco = AssistenteMapper::getEnderecoFromAssistenteUpdateVM( $assistente_update_vm );
		$sucess_update = $endereco_model->updateEnderecoByAssistenteID( $id_paciente, $endereco );
		return $sucess_update;

	}

	private function persistPessoaFromAssistenteUpdateVM(int $id_assistente, AssistenteUpdateViewModel &$assistente_update_vm): bool {

		$pessoa_model = new PessoaModel();
		$pessoa = AssistenteMapper::getPessoaFromAssistenteUpdateVM( $assistente_update_vm );
		$sucess_update = $pessoa_model->updatePessoaByAssistenteID( $id_assistente, $pessoa );
		return $sucess_update;

	}

	private function persistPessoaFisicaFromAssistenteUpdateVM(int $id_assistente, AssistenteUpdateViewModel &$assistente_update_vm): bool {

		$pessoa_fisica_model = new PessoaFisicaModel();
		$pessoa_fisica = AssistenteMapper::getPessoaFisicaFromAssistenteUpdateVM( $assistente_update_vm );
		$sucess_update = $pessoa_fisica_model->updatePessoaFisicaByAssistenteID( $id_assistente, $pessoa_fisica );
		return $sucess_update;

	}

	private function persistUsuarioFromAssistenteUpdateVM(int $id_assistente, AssistenteUpdateViewModel &$assistente_update_vm): bool {

		$usuario_model = new UsuarioModel();
		$usuario = AssistenteMapper::getUsuarioFromAssistenteUpdateVM( $assistente_update_vm );
		$sucess_update = $usuario_model->updateUsuarioByAssistenteID( $id_assistente, $usuario );
		return $sucess_update;

	}

	private function persistUsuarioPerfilFromAssistenteUpdateVM(int $id_assistente, AssistenteUpdateViewModel &$assistente_update_vm): bool {

		$usuario_model = new UsuarioPerfilModel();
		$usuario = AssistenteMapper::getUsuarioPerfilFromAssistenteUpdateVM( $assistente_update_vm );
		$sucess_update = $usuario_model->updatePerfilByAssistenteID( $id_assistente, $usuario );
		return $sucess_update;

	}

	private function persistPacienteFromAssistenteUpdateVM(int $id_assistente, AssistenteUpdateViewModel &$assistente_update_vm): bool {

		$paciente_model = new PacienteModel();
		$paciente = AssistenteMapper::getPacienteFromAssistenteUpdateVM( $assistente_update_vm );
		$sucess_update = $paciente_model->updatePacienteByAssistenteID( $id_assistente, $paciente );
		return $sucess_update;

	}

	private function persistAssistenteMedicoFromAssistenteUpdateVM(int $id_assistente, AssistenteUpdateViewModel &$assistente_update_vm): bool {

		$assistente_medico_model = new AssistenteMedicoModel();
		$this->deleteMedicosFromAssistenteList( $id_assistente );
		$sucess = true;

		foreach ( $assistente_update_vm->getIdMedico() as $value ) :
			$assistente_medico = AssistenteMapper::getAssistenteMedicoFromAssistenteRegistrationVM( $value, $id_assistente );
			$assistente_medico_model->registerAssistenteMedico( $assistente_medico );
			if (!$assistente_medico->getId()) {
				$sucess = false;
			}
		endforeach
		;
		return $sucess;

	}

	public function deleteMedicosFromAssistenteList(int $id_assistente) {

		$sql = '
            DELETE FROM assistente_medico WHERE id_assistente = :id_assistente:
        ';
		$binds = [ 
			'id_assistente' => $id_assistente
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return $result_array;

	}

	public function getImageAssistente(int $id_assistente) {

		$sql = '
            SELECT
                usuario.foto as foto
            FROM assistente, pessoa, profissional, pessoa_fisica, usuario, endereco, cep
            WHERE 
                assistente.id_profissional = profissional.id AND
                profissional.id_pessoa = pessoa.id AND
                pessoa.id = pessoa_fisica.id_pessoa AND
                pessoa.id = usuario.id_pessoa AND
                pessoa.id_endereco = endereco.id AND
                endereco.cep = cep.id AND
            	usuario.ativo = 1 AND assistente.id = :id_assistente:
        ';
		$binds = [ 
			'id_assistente' => $id_assistente
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return (($result_array [0] ['foto']));

	}

	public function getAssistenteFromId(int $id_assistente) {

		$sql = '
            SELECT 1
            FROM assistente
            WHERE assistente.id = :id_assistente:
        ';
		$binds = [ 
			'id_assistente' => $id_assistente
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return ($result_array);

	}

	public function getUsuarioIdByAssistenteID(int $id_assistente): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			select u.id as id_usuario  
			from assistente a, profissional p, usuario u
			where a.id = :assistente_id: and a.id_profissional = p.id and p.id_pessoa = u.id_pessoa
		SQL;
		$binds = [ 
			'assistente_id' => $id_assistente
		];

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

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

		return $dao_response;

	}

	public function getAssistenteIDFromUsuarioID(int $id_usuario): DAOResponse {

		$sql = '
            SELECT
                assistente.id as id_assistente
            FROM
                usuario, profissional, assistente
            WHERE
                usuario.id_pessoa = profissional.id_pessoa AND
                assistente.id_profissional = profissional.id AND
                usuario.id = :id_usuario:
        ';
		$binds = [ 
			'id_usuario' => $id_usuario
		];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, null, $sql,
			function (array $result_array): int {
				return ( int ) $result_array [0] ['id_assistente'];
			} );

	}

	public function getAssistenteAviableToRequisicao(int $requisicaoId): DAOResponse {

		$sql = <<<SQL
				select
					rp.id ,cp.id_unidade, pc.id_profissional ,
					a.id as assistente_id, u.id as usuario_id, pf.nome
				from
					requisicao_procedimento rp, convenio_procedimento cp , unidade un , profissional_clinica pc,
					assistente a , profissional p , usuario u, usuario_perfil up , pessoa_fisica pf
				where
					rp.id = :id_requisicao:
					and rp.id_convenio_procedimento = cp.id
					and cp.id_unidade = un.id
					and un.id_pessoa_juridica = pc.id_pessoa_juridica
					and pc.id_profissional = a.id_profissional
					and a.id_profissional = p.id
					and p.id_pessoa = u.id_pessoa
					and u.id = up.id_usuario
					and up.id_perfil = 3
					and u.id_pessoa = pf.id_pessoa
		SQL;

		$binds = [ 
			'id_requisicao' => $requisicaoId
		];
		$dao_response = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

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

		return $dao_response;

	}

	public function getUsuarioIDFromAssitenteID(int $id_assistente): DAOResponse {

		$sql = <<<SQL
				select u.id
				from
					assistente a , profissional p , usuario u , usuario_perfil up
				where
					a.id = :assistente_id:
					and a.id_profissional = p.id
					and p.id_pessoa = u.id_pessoa
					and u.id = up.id_usuario
					and up.id_perfil = 3
		SQL;

		$binds = [ 
			'assistente_id' => $id_assistente
		];
		$dao_response = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

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

		return $dao_response;

	}

	public function getAssistenteByUnidadeID(int $id_unidade): DAOResponse {

		$sql = <<<SQL
			select 
				a.id as id_assistente, u.id as id_usuario , pf.nome
			from
				unidade un, assistente a , profissional p , profissional_clinica pc ,
				usuario u , usuario_perfil up , pessoa_fisica pf
			where
				un.id = :unidade_id:
				and un.id_pessoa_juridica = pc.id_pessoa_juridica
				and pc.id_profissional = p.id
				and p.id = a.id_profissional
				and p.id_pessoa = u.id_pessoa
				and p.id_pessoa = pf.id_pessoa
				and u.id = up.id_usuario
				and up.id_perfil = 3
		SQL;

		$binds = [ 
			'unidade_id' => $id_unidade
		];
		$dao_response = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

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

		return $dao_response;

	}

}