<?php

namespace App\DAO;

use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
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\Administrativo\Administrativo;
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\AdministrativoMapper;
use App\Models\CEPModel;
use App\Models\ClienteModel;
use App\Models\ConfirmacaoEmailModel;
use App\Models\EnderecoModel;
use App\Models\AdministrativoModel;
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\Administrativo\AdministrativoRegistrationViewModel\AdministrativoRegistrationViewModel;
use App\ViewModels\Administrativo\AdministrativoUpdateViewModel\AdministrativoUpdateViewModel;
use Exception;

class AdministrativoDAO extends DAO {

	public function persistAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, callable $send_email): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$this->db->transStart();
			$cep = $this->persistCepFromAdministrativoRegistrationVM( $administrativo_registration_vm );
			$endereco = $this->persistEnderecoFromAdministrativoRegistrationVM( $administrativo_registration_vm, $cep );
			$pessoa = $this->persistPessoaFromAdministrativoRegistrationVM( $administrativo_registration_vm, $endereco );
			$usuario = $this->persistUsuarioFromAdministrativoRegistrationVM( $administrativo_registration_vm, $pessoa );
			$paciente = $this->persistPacienteFromAdministrativoRegistrationVM( $administrativo_registration_vm, $pessoa );
			# $cliente = $this->persistClienteFromAdministrativoRegistrationVM( $administrativo_registration_vm, $pessoa );
			$pessoa_fisica = $this->persistPessoaFisicaFromAdministrativoRegistrationVM( $administrativo_registration_vm, $pessoa );
			$usuario_perfil = $this->persistUsuarioPerfilFromAdministrativoRegistrationVM( $administrativo_registration_vm, $usuario );
			$profissional = $this->persistProfissionalFromAdministrativoRegistrationVM( $administrativo_registration_vm, $pessoa );
			$profissional_clinica = $this->persistProfissionalClinicaFromAdministrativoRegistrationVM( $administrativo_registration_vm, $profissional );
			$administrativo = $this->persistAdministrativoFromAdministrativoRegistrationVM( $administrativo_registration_vm, $profissional );
			// if ($administrativo_registration_vm->getTokenConfirmacaoEmail()) {
			// $confirmacao_email = $this->persistConfirmacaoEmailFromAdministrativoRegistrationVM( $administrativo_registration_vm, $usuario );
			// }

			$error = $this->db->error();
			if ($error && $error ['code']) {
				$this->setDatabaseErrorsForAdministrativoRegistration( $dao_response, $error );
			} else {
				$status_service_response_send_email = ServiceResponseInterface::SUCESS;

				// $status_service_response_send_email = $send_email();
				if ($status_service_response_send_email === ServiceResponseInterface::SUCESS) {
					$dao_response->setStatus( DAOResponseInterface::SUCESS );
					$dao_response->setData( $administrativo );
					$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 administrativo.', $administrativo_registration_vm->toArray() );
					$dao_response->setStatus( DAOResponseInterface::INTERNAL_DAO_ERROR );
				}
			}
		} catch ( Exception $exception ) {
			$this->setDatabaseErrorsForAdministrativoRegistration( $dao_response, $this->db->error() );
		}
		return $dao_response;

	}

	private function setDatabaseErrorsForAdministrativoRegistration(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 persistCepFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm): CEP {

		$cep_model = new CEPModel();
		$cep = AdministrativoMapper::getCepFromAdministrativoRegistrationVM( $administrativo_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 persistEnderecoFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm, CEP $cep): Endereco {

		$endereco_model = new EnderecoModel();
		$endereco = AdministrativoMapper::getEnderecoFromAdministrativoRegistrationVM( $administrativo_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 persistPessoaFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm, Endereco &$endereco): Pessoa {

		$pessoa_model = new PessoaModel();
		$pessoa = AdministrativoMapper::getPessoaFromAdministrativoRegistrationVM( $administrativo_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 persistPessoaFisicaFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm, Pessoa &$pessoa): PessoaFisica {

		$pessoa_fisica_model = new PessoaFisicaModel();
		$pessoa_fisica = AdministrativoMapper::getPessoaFisicaFromAdministrativoRegistrationVM( $administrativo_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 persistUsuarioFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm, Pessoa &$pessoa): Usuario {

		$usuario_model = new UsuarioModel();
		$usuario = AdministrativoMapper::getUsuarioFromAdministrativoRegistrationVM( $administrativo_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 persistPacienteFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$paciente_registration_vm, Pessoa &$pessoa): Paciente {

		$paciente_model = new PacienteModel();
		$paciente = AdministrativoMapper::getPacienteFromAdministrativoRegistrationVM( $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 persistClienteFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm, Pessoa &$pessoa): Cliente {

		$cliente_model = new CLienteModel();
		$cliente = AdministrativoMapper::getClienteFromAdministrativoRegistrationVM( $administrativo_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 persistUsuarioPerfilFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm,
			Usuario &$usuario): UsuarioPerfil {

		$usuario_perfil_model = new UsuarioPerfilModel();
		$usuario_perfil = AdministrativoMapper::getUsuarioPerfilFromAdministrativoRegistrationVM( $administrativo_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 persistConfirmacaoEmailFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm,
			Usuario &$usuario): ConfirmacaoEmail {

		$confirmacao_email_model = new ConfirmacaoEmailModel();
		$confirmacao_email = AdministrativoMapper::getConfirmacaoEmailFromAdministrativoRegistrationVM( $administrativo_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 persistProfissionalFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm, Pessoa &$pessoa): Profissional {

		$profissional_model = new ProfissionalModel();
		$profissional = AdministrativoMapper::getProfissionalFromAdministrativoRegistrationVM( $administrativo_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 persistProfissionalClinicaFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm,
			Profissional &$pessoa): ProfissionalClinica {

		$profissional_clinica_model = new ProfissionalClinicaModel();
		$array = explode( ",", $administrativo_registration_vm->getIdClinica() );
		foreach ( $array as $unidade ) :
			$profissional_clinica = AdministrativoMapper::getProfissionalClinicaFromProfissionalClinicaRegistrationVM( $administrativo_registration_vm, $pessoa,
				$unidade );
			$profissional_clinica_model->registerProfissionalClinica( $profissional_clinica );
			if (!$profissional_clinica->getId()) {
				throw new Exception( 'O cadastro de administrativo_clinica não foi teve êxito' );
			}
		endforeach
		;
		return $profissional_clinica;

	}

	private function persistAdministrativoFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel &$administrativo_registration_vm,
			Profissional &$pessoa): Administrativo {

		$administrativo_model = new AdministrativoModel();
		$administrativo = AdministrativoMapper::getAdministrativoFromAdministrativoRegistrationVM( $administrativo_registration_vm, $pessoa );
		$administrativo_model->registerAdministrativo( $administrativo );
		if (!$administrativo->getId()) {
			throw new Exception( 'O cadastro de administrativo não teve êxito' );
		}
		return $administrativo;

	}

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

		$is_unidade = 0;
		if (!is_null( $query_filter_collection )) {
			$arr = $query_filter_collection->toArray();
			for($i = 0; $i < count( $arr ); $i++) {
				$item = $arr [$i];
				if ($item ['table'] == 'unidade' && $item ['name_param'] == 'id') {
					$is_unidade = 1;
					break;
				}
			}
		}

		if ($is_unidade == 0) {
			$sql = <<<SQL
				SELECT
					administrativo.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, 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.ativo as ativo, usuario_status.descricao as ativo_desc, usuario.foto as foto,
					perfil.id as id_perfil, perfil.descricao as descricao_perfil
				FROM
					perfil, administrativo, pessoa, profissional, pessoa_fisica,
					usuario, endereco, cep,	 usuario_perfil, usuario_status
				WHERE
					perfil.id = 1
					AND administrativo.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.id = usuario_perfil.id_usuario
					AND usuario_perfil.id_perfil = perfil.id
					AND usuario.ativo = usuario_status.id
			SQL;
		} else {
			$sql = <<<SQL
				SELECT DISTINCT
					administrativo.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, 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.ativo as ativo, usuario_status.descricao as ativo_desc, usuario.foto as foto,
					perfil.id as id_perfil, perfil.descricao as descricao_perfil
				FROM
					perfil, administrativo, pessoa, profissional, pessoa_fisica,
					usuario, endereco, cep,	 usuario_perfil, usuario_status,
					profissional_clinica, unidade
				WHERE
					perfil.id = 1
					AND administrativo.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.id = usuario_perfil.id_usuario
					AND usuario_perfil.id_perfil = perfil.id
					AND usuario.ativo = usuario_status.id
					AND profissional.id = profissional_clinica.id_profissional 
					AND profissional_clinica.id_pessoa_juridica = unidade.id_pessoa_juridica 
			SQL;
		}

		$binds = [ ];
		return $this->getDAOResponseFromPaginatedSelect( $binds, $pagination, $query_filter_collection, $query_order_collection, $sql,
			function (array $result_array) {
				return AdministrativoMapper::getAdministrativoDetailsVMListFromArray( $result_array );
			} );

	}

	public function getAdministrativo(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = <<<SQL
			SELECT
				administrativo.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, 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.ativo as ativo, usuario_status.descricao as ativo_desc, usuario.foto as foto,
				pessoa_juridica.id as id_clinica, pessoa_juridica.nome_fantasia as nome_fantasia,
				perfil.id as id_perfil, perfil.descricao as descricao_perfil
			FROM
				perfil, administrativo, pessoa, profissional, pessoa_fisica, usuario, endereco, cep,
				pessoa_juridica, profissional_clinica, usuario_perfil, usuario_status
			WHERE
				perfil.id = 1
				AND administrativo.id_profissional = profissional.id
				AND administrativo.id_profissional = profissional_clinica.id_profissional
				AND profissional_clinica.id_pessoa_juridica = pessoa_juridica.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.id = usuario_perfil.id_usuario
				AND usuario_perfil.id_perfil = perfil.id
				AND usuario.ativo = usuario_status.id
		SQL;
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
			function (array $result_array) {
				return AdministrativoMapper::getAdministrativoDetailsVMFromArray( $result_array [0] );
			} );

	}

	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 verifyAdministrativoAndMedicoAreLinked(int $id_medico, int $administrativo_uid): DAOResponse {

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

	}

	public function persistAdministrativoUpdateVM(int $id_paciente, AdministrativoUpdateViewModel $administrativo_update_vm): DAOResponse {

		$dao_response = new DAOResponse();
		$this->db->transStart();
		$status_persistence = $this->persistCepFromAdministrativoUpdateVM( $id_paciente, $administrativo_update_vm );
		$status_persistence = $this->persistEnderecoFromAdministrativoUpdateVM( $id_paciente, $administrativo_update_vm );
		$status_persistence = $status_persistence && $this->persistPessoaFromAdministrativoUpdateVM( $id_paciente, $administrativo_update_vm );
		$status_persistence = $status_persistence && $this->persistUsuarioFromAdministrativoUpdateVM( $id_paciente, $administrativo_update_vm );
		$status_persistence = $status_persistence && $this->persistPacienteFromAdministrativoUpdateVM( $id_paciente, $administrativo_update_vm );
		$status_persistence = $status_persistence && $this->persistPessoaFisicaFromAdministrativoUpdateVM( $id_paciente, $administrativo_update_vm );
		// $status_persistence = $status_persistence && $this->persistProfissionalClinicaFromAdministrativoUpdateVM( $id_paciente, $administrativo_update_vm );
		$error = $this->db->error();
		if ($error && $error ['code']) {
			$this->setDatabaseErrorsForAdministrativoUpdate( $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 setDatabaseErrorsForAdministrativoUpdate(DAOResponse $dao_response, array $error): void {

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

	}

	private function persistCepFromAdministrativoUpdateVM(int $id_paciente, AdministrativoUpdateViewModel &$paciente_update_vm): bool {

		$cep_model = new CEPModel();
		$cep = AdministrativoMapper::getCepFromAdministrativoUpdateVM( $paciente_update_vm );
		$sucess_update = $cep_model->updateCepByAdministrativoID( $id_paciente, $cep );
		return $sucess_update;

	}

	private function persistEnderecoFromAdministrativoUpdateVM(int $id_paciente, AdministrativoUpdateViewModel &$administrativo_update_vm): bool {

		$endereco_model = new EnderecoModel();
		$endereco = AdministrativoMapper::getEnderecoFromAdministrativoUpdateVM( $administrativo_update_vm );
		$sucess_update = $endereco_model->updateEnderecoByAdministrativoID( $id_paciente, $endereco );
		return $sucess_update;

	}

	private function persistPessoaFromAdministrativoUpdateVM(int $id_administrativo, AdministrativoUpdateViewModel &$administrativo_update_vm): bool {

		$pessoa_model = new PessoaModel();
		$pessoa = AdministrativoMapper::getPessoaFromAdministrativoUpdateVM( $administrativo_update_vm );
		$sucess_update = $pessoa_model->updatePessoaByAdministrativoID( $id_administrativo, $pessoa );
		return $sucess_update;

	}

	private function persistPessoaFisicaFromAdministrativoUpdateVM(int $id_administrativo, AdministrativoUpdateViewModel &$administrativo_update_vm): bool {

		$pessoa_fisica_model = new PessoaFisicaModel();
		$pessoa_fisica = AdministrativoMapper::getPessoaFisicaFromAdministrativoUpdateVM( $administrativo_update_vm );
		$sucess_update = $pessoa_fisica_model->updatePessoaFisicaByAdministrativoID( $id_administrativo, $pessoa_fisica );
		return $sucess_update;

	}

	private function persistUsuarioFromAdministrativoUpdateVM(int $id_administrativo, AdministrativoUpdateViewModel &$administrativo_update_vm): bool {

		$usuario_model = new UsuarioModel();
		$usuario = AdministrativoMapper::getUsuarioFromAdministrativoUpdateVM( $administrativo_update_vm );
		$sucess_update = $usuario_model->updateUsuarioByAdministrativoID( $id_administrativo, $usuario );
		return $sucess_update;

	}

	private function persistPacienteFromAdministrativoUpdateVM(int $id_administrativo, AdministrativoUpdateViewModel &$administrativo_update_vm): bool {

		$paciente_model = new PacienteModel();
		$paciente = AdministrativoMapper::getPacienteFromAdministrativoUpdateVM( $administrativo_update_vm );
		$sucess_update = $paciente_model->updatePacienteByAdministrativoID( $id_administrativo, $paciente );
		return $sucess_update;

	}

	private function persistProfissionalClinicaFromAdministrativoUpdateVM(int $id_administrativo, AdministrativoUpdateViewModel &$administrativo_update_vm): bool {

		$profissional_clinica_model = new ProfissionalClinicaModel();
		$profissional_clinica = AdministrativoMapper::getProfissionalClinicaFromProfissionalClinicaUpdateVM( $administrativo_update_vm );
		$sucess_update = $profissional_clinica_model->updateProfissionalClinicaByAdministrativoID( $id_administrativo, $profissional_clinica );
		return $sucess_update;

	}

	public function getImageAdministrativo(int $id_administrativo) {

		$sql = '
            SELECT
                usuario.foto as foto
            FROM administrativo, pessoa, profissional, pessoa_fisica, usuario, endereco, cep
            WHERE 
                administrativo.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 administrativo.id = :id_administrativo:
        ';
		$binds = [ 
			'id_administrativo' => $id_administrativo
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return (($result_array [0] ['foto']));

	}

	public function getAdministrativoFromId(int $id_administrativo) {

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

	}

	public function getUnidadesAdministrativo(int $id_adm) {

		$sql = '
            SELECT
            u.id as id_unidade,
            u.descricao as descricao_unidade,
            u.id_pessoa_juridica as id_pessoa_juridica
            FROM administrativo m
            INNER JOIN profissional_clinica pc on pc.id_profissional = m.id_profissional
            INNER JOIN unidade u on u.id_pessoa_juridica = pc.id_pessoa_juridica
            WHERE m.id = :id_adm:
        ';
		$binds = [ 
			'id_adm' => $id_adm
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return ($result_array);

	}

}
