<?php

namespace App\Mappers;

use App\DAO\UnidadeDAO;
use App\Entities\Assistente\Assistente;
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\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\Recepcao\Recepcionista;
use App\Entities\Usuario\Usuario;
use App\Entities\UsuarioPerfil\UsuarioPerfil;
use App\Services\JWTService;
use App\Services\UnidadeService;
use App\Utils\Collections\GeneralCollection;
use App\Utils\DateUtils;
use App\ViewModels\Recepcao\RecepcaoRegistrationViewModel\RecepcaoRegistrationViewModel;
use App\ViewModels\Recepcao\RecepcionistaDetailsViewModel\RecepcionistaDetailsViewModel;
use App\ViewModels\Recepcao\RecepcionistaRegistrationViewModel\RecepcionistaRegistrationViewModel;
use App\ViewModels\Recepcao\RecepcionistaUpdateViewModel\RecepcionistaUpdateViewModel;

class RecepcaoMapper {

	public function RecepcionistaRegistrationViewModelMapper(array $recepcionista): RecepcionistaRegistrationViewModel {

		$jwt_payload = JWTService::getTokenJWTPayload();
		$uid = $jwt_payload ? $jwt_payload->getUid() : null;
		$recepcao_registration_vm = RecepcionistaRegistrationViewModel::builder()->setFoto( $recepcionista ['foto'] )
			->setNome( ucwords( $recepcionista ['nome'] ) )
			->setEmail( $recepcionista ['email'] )
			->setRg( $recepcionista ['rg'] )
			->setGenero( $recepcionista ['genero'] )
			->setDataNascimento( $recepcionista ['data_nascimento'] )
			->setEstadoCivil( $recepcionista ['estado_civil'] )
			->setCep( $recepcionista ['cep'] )
			->setNumero( $recepcionista ['numero'] )
			->setComplemento( $recepcionista ['complemento'] )
			->setReferencias( $recepcionista ['referencias'] )
			->setCpf( $recepcionista ['cpf'] )
			->setTelefone1( $recepcionista ['telefone_1'] )
			->setTelefone2( $recepcionista ['telefone_2'] )
			->setTelefone3( $recepcionista ['telefone_3'] ?? '')
			->setAdicionadoPor( $uid )
			->setProfissao( $recepcionista ['profissao'] )
			->setIndicadoPor( $uid )
			->setSenha( $recepcionista ['senha'] )
			->setAtivo( $recepcionista ['ativo'] )
			->setTokenConfirmacaoEmail( $recepcionista ['token_confirmacao_email'] )
			->setCidade( $recepcionista ['cidade'] )
			->setEstado( $recepcionista ['estado'] )
			->setBairro( $recepcionista ['bairro'] )
			->setLogradouro( $recepcionista ['logradouro'] )
			->setPerfilId( $recepcionista ['id_perfil'] )
			->setUnidades( $recepcionista ['unidades'] )
			->setSenhaChameFacil( $recepcionista ['senha_chamefacil'] )
			->build();
		return $recepcao_registration_vm;

	}

	public static function getRecepcionistaListVMFromArray(array $assistente): RecepcionistaDetailsViewModel {

		$assistente_details_vm = RecepcionistaDetailsViewModel::builder()->setId( $assistente ['id'] )
			->setCpf( $assistente ['cpf'] )
			->setRg( $assistente ['rg'] )
			->setNome( $assistente ['nome'] )
			->setGenero( $assistente ['genero'] )
			->setDataNascimento( $assistente ['data_nascimento'] )
			->setTelefone1( $assistente ['telefone_1'] )
			->setTelefone2( $assistente ['telefone_2'] )
			->setTelefone3( $assistente ['telefone_3'] ?? '')
			->setCep( $assistente ['cep'] )
			->setNumero( $assistente ['numero'] )
			->setComplemento( $assistente ['complemento'] )
			->setReferencias( $assistente ['referencias'] )
			->setEstado( $assistente ['estado'] )
			->setCidade( $assistente ['cidade'] )
			->setBairro( $assistente ['bairro'] )
			->setLogradouro( $assistente ['logradouro'] )
			->setEmail( $assistente ['email'] )
			->setFoto( "" )
			->setAtivo( $assistente ['ativo'] )
			->setAtivoDescricao( $assistente ['ativo_desc'] ?? '-')
			->setProfissao( $assistente ['profissao'] )
			->setEstadoCivil( $assistente ['estado_civil'] )
			->
		// ->setPerfilId($assistente['perfil_id'])
		setPerfilDescricao( $assistente ['perfil_descricao'] )
			->build();
		return $assistente_details_vm;

	}

	public static function getRecepcionistaDetailsVMFromArray(array $recepcionista): RecepcionistaDetailsViewModel {

		if (file_exists( $recepcionista ['foto'] ) === true) {
			$get_file = file_get_contents( $recepcionista ['foto'] );
			$ext = pathinfo( $recepcionista ['foto'], PATHINFO_EXTENSION );
			$filebase64 = base64_encode( $get_file );
		} else {
			$get_file = file_get_contents( "../writable/perfil/default.png" );
			$ext = "png";
			$filebase64 = base64_encode( $get_file );
		}

		$recepcionista_details_vm = RecepcionistaDetailsViewModel::builder()->setId( $recepcionista ['id'] )
			->setCpf( $recepcionista ['cpf'] )
			->setRg( $recepcionista ['rg'] )
			->setNome( $recepcionista ['nome'] )
			->setGenero( $recepcionista ['genero'] )
			->setDataNascimento( $recepcionista ['data_nascimento'] )
			->setTelefone1( $recepcionista ['telefone_1'] )
			->setTelefone2( $recepcionista ['telefone_2'] )
			->setTelefone3( $recepcionista ['telefone_3'] ?? '')
			->setCep( $recepcionista ['cep'] )
			->setNumero( $recepcionista ['numero'] )
			->setComplemento( $recepcionista ['complemento'] )
			->setReferencias( $recepcionista ['referencias'] )
			->setEstado( $recepcionista ['estado'] )
			->setCidade( $recepcionista ['cidade'] )
			->setBairro( $recepcionista ['bairro'] )
			->setLogradouro( $recepcionista ['logradouro'] )
			->setEmail( $recepcionista ['email'] )
			->setFoto( $filebase64 ?? [ ])
			->setAtivo( $recepcionista ['ativo'] )
			->setAtivoDescricao( $recepcionista ['ativo_desc'] ?? '-')
			->setProfissao( $recepcionista ['profissao'] )
			->setEstadoCivil( $recepcionista ['estado_civil'] )
			->setPerfilId( $recepcionista ['perfil_id'] )
			->setIdUsuario( $recepcionista ['id_usuario'] )
			->
		// ->setPerfilDescricao($recepcionista['perfil_descricao'])
		setTipo( $ext )
			->build();
		return $recepcionista_details_vm;

	}

	public static function getRecepcionistaDetailsVMListFromArray(array $recepcionista_list): GeneralCollection {

		$recepcionista_details_vm_collection = new GeneralCollection();
		for($i = 0, $number_recepcionista = count( $recepcionista_list ); $i < $number_recepcionista; $i++) {
			$recepcionista_details_vm_collection->push( RecepcaoMapper::getRecepcionistaListVMFromArray( $recepcionista_list [$i] ) );
		}
		$teste = $recepcionista_details_vm_collection;
		return $recepcionista_details_vm_collection;

	}

	public static function getRecepcionistaDetailsArrayFromRecepcionistaDetailsVMList(GeneralCollection $paciente_details_vm_collection): array {

		return $paciente_details_vm_collection->toArray();

	}

	public static function getCepFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm): CEP {

		$endereco = CEP::builder()->setCep( $recepcao_registration_vm->getCep() )
			->setEstado( $recepcao_registration_vm->getEstado() )
			->setBairro( $recepcao_registration_vm->getBairro() )
			->setCidade( $recepcao_registration_vm->getCidade() )
			->setLogradouro( $recepcao_registration_vm->getLogradouro() )
			->build();
		return $endereco;

	}

	public static function getEnderecoFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, CEP $cep): Endereco {

		$endereco = Endereco::builder()->setCep( $cep->getId() )
			->setNumero( $recepcao_registration_vm->getNumero() )
			->setComplemento( $recepcao_registration_vm->getComplemento() )
			->setReferencias( $recepcao_registration_vm->getReferencias() )
			->build();
		return $endereco;

	}

	public static function getPessoaFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Endereco $endereco): Pessoa {

		$pessoa = Pessoa::builder()->setTelefone1( $recepcao_registration_vm->getTelefone1() )
			->setTelefone2( $recepcao_registration_vm->getTelefone2() )
			->setIdEndereco( $endereco->getId() )
			->setIdTipoPessoa( PESSOA_FISICA_ID )
			->setAdicionadoPor( $recepcao_registration_vm->getAdicionadoPor() )
			->build();
		return $pessoa;

	}

	public static function getPessoaFisicaFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Pessoa $pessoa): PessoaFisica {

		$pessoa_fisica = PessoaFisica::builder()->setIdPessoa( $pessoa->getId() )
			->setCpf( $recepcao_registration_vm->getCpf() )
			->setRg( $recepcao_registration_vm->getRg() )
			->setGenero( $recepcao_registration_vm->getGenero() )
			->setDataNascimento( $recepcao_registration_vm->getDataNascimento() )
			->setNome( $recepcao_registration_vm->getNome() )
			->setProfissao( '' )
			->setEstadoCivil( $recepcao_registration_vm->getEstadoCivil() )
			->build();
		return $pessoa_fisica;

	}

	public static function getUsuarioFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Pessoa $pessoa): Usuario {

		$usuario = Usuario::builder()->setEmail( $recepcao_registration_vm->getEmail() )
			->setSenha( $recepcao_registration_vm->getSenha() )
			->setAtivo( $recepcao_registration_vm->getAtivo() )
			->setFoto( $recepcao_registration_vm->getFoto() ?? '')
			->setEmailVerificadoEm( $recepcao_registration_vm->getTokenConfirmacaoEmail() ? null : DateUtils::now() )
			->setIdPessoa( $pessoa->getId() )
			->setAdicionadoPor( $recepcao_registration_vm->getAdicionadoPor() )
			->setSenhaChameFacil( $recepcao_registration_vm->getSenhaChameFacil() )
			->build();
		return $usuario;

	}

	public static function getPacienteFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Pessoa $pessoa): Paciente {

		$assistente = Paciente::builder()->setAdicionadoPor( $recepcao_registration_vm->getAdicionadoPor() )
			->setIdPessoa( $pessoa->getId() )
			->setIndicadoPor( "" )
			->build();
		return $assistente;

	}

	public static function getClienteFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Pessoa $pessoa): Cliente {

		$cliente = Cliente::builder()->setAdicionadoPor( $recepcao_registration_vm->getAdicionadoPor() )
			->setIdPessoa( $pessoa->getId() )
			->build();
		return $cliente;

	}

	public static function getConfirmacaoEmailFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Usuario $usuario): ConfirmacaoEmail {

		$confirmacao_email = ConfirmacaoEmail::builder()->setIdUsuario( $usuario->getId() )
			->setToken( $recepcao_registration_vm->getTokenConfirmacaoEmail() )
			->setTempoExpiracao( EMAIL_TOKEN_EXPIRATION_TIME )
			->build();
		return $confirmacao_email;

	}

	public static function getUsuarioPerfilFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Usuario $usuario): UsuarioPerfil {

		$usuario_perfil = UsuarioPerfil::builder()->setIdUsuario( $usuario->getId() )
			->setIdPerfil( $recepcao_registration_vm->getPerfilId() )
			->build();
		return $usuario_perfil;

	}

	public static function getProfissionalFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Pessoa $pessoa): Profissional {

		$profissional = Profissional::builder()->setAdicionadoPor( $recepcao_registration_vm->getAdicionadoPor() )
			->setIdPessoa( $pessoa->getId() )
			->build();
		return $profissional;

	}

	public static function getProfissionalClinicaFromProfissionalClinicaRegistrationVM($recepcao_registration_vm, Profissional $pessoa): ProfissionalClinica {

		$unidadeDAO = new UnidadeDAO();
		$id_pessoa_juidica = $unidadeDAO->getIdCfUnidade( ( int ) $recepcao_registration_vm );

		$profissional_clinica = ProfissionalClinica::builder()->setIdProfissional( $pessoa->getId() )
			->setIdPessoaJuridica( $id_pessoa_juidica [0] ['id_pessoa_juridica'] )
			->build();

		return $profissional_clinica;

	}

	public static function getAssistenteFromRecepcaoRegistrationVM(RecepcionistaRegistrationViewModel $recepcao_registration_vm, Profissional $pessoa): Recepcionista {

		$recepcionista = Recepcionista::builder()->setIdProfissional( $pessoa->getId() )
			->build();
		return $recepcionista;

	}

	public static function getAssistenteMedicoFromAssistenteRegistrationVM($value, $id_assistente): AssistenteMedico {

		$profissional_clinica = AssistenteMedico::builder()->setIdASSISTENTE( $id_assistente )
			->setIdMEDICO( $value )
			->build();
		return $profissional_clinica;

	}

	public static function getRecepcionistaUpdateVMFromArray(array $recepcionista_data): RecepcionistaUpdateViewModel {

		$recepcionista_update_vm = new RecepcionistaUpdateViewModel();
		if (isset( $recepcionista_data ['cpf'] )) {
			$recepcionista_update_vm->setCpf( $recepcionista_data ['cpf'] );
		}
		if (isset( $recepcionista_data ['rg'] )) {
			$recepcionista_update_vm->setRg( $recepcionista_data ['rg'] );
		}
		if (isset( $recepcionista_data ['nome'] )) {
			$recepcionista_update_vm->setNome( ucwords( $recepcionista_data ['nome'] ) );
		}
		if (isset( $recepcionista_data ['ativo'] )) {
			$recepcionista_update_vm->setAtivo( ucwords( $recepcionista_data ['ativo'] ) );
		}
		if (isset( $recepcionista_data ['genero'] )) {
			$recepcionista_update_vm->setGenero( $recepcionista_data ['genero'] );
		}
		if (isset( $recepcionista_data ['data_nascimento'] )) {
			$recepcionista_update_vm->setDataNascimento( $recepcionista_data ['data_nascimento'] );
		}
		if (isset( $recepcionista_data ['telefone_1'] )) {
			$recepcionista_update_vm->setTelefone1( $recepcionista_data ['telefone_1'] );
		}
		if (isset( $recepcionista_data ['telefone_2'] )) {
			$recepcionista_update_vm->setTelefone2( $recepcionista_data ['telefone_2'] );
		}
		if (isset( $recepcionista_data ['telefone_3'] )) {
			$recepcionista_update_vm->setTelefone3( $recepcionista_data ['telefone_3'] ?? '');
		}
		if (isset( $recepcionista_data ['cep'] )) {
			$recepcionista_update_vm->setCep( $recepcionista_data ['cep'] );
		}
		if (isset( $recepcionista_data ['numero'] )) {
			$recepcionista_update_vm->setNumero( $recepcionista_data ['numero'] );
		}
		if (isset( $recepcionista_data ['complemento'] )) {
			$recepcionista_update_vm->setComplemento( $recepcionista_data ['complemento'] );
		}
		if (isset( $recepcionista_data ['referencias'] )) {
			$recepcionista_update_vm->setReferencias( $recepcionista_data ['referencias'] );
		}
		if (isset( $recepcionista_data ['id_perfil'] )) {
			$recepcionista_update_vm->setPerfilId( $recepcionista_data ['id_perfil'] );
		}
		if (isset( $_FILES ['foto'] )) {
			$ext = "." . pathinfo( $_FILES ['foto'] ['name'], PATHINFO_EXTENSION );
			// $ext = strtolower(substr($_FILES['foto']['name'], -4)); //Pegando extensão do arquivo
			$new_name = date( "Y.m.d-H.i.s" ) . $ext; // Definindo um novo nome para o arquivo
			$dir = '../writable/perfil/';
			move_uploaded_file( $_FILES ['foto'] ['tmp_name'], $dir . $new_name ); // Fazer upload do arquivo
			$recepcionista_data ['foto'] = $dir . $new_name;
		}

		if (isset( $recepcionista_data ['foto'] )) {
			$recepcionista_update_vm->setFoto( $recepcionista_data ['foto'] );
		}
		if (isset( $recepcionista_data ['profissao'] )) {
			$recepcionista_update_vm->setProfissao( $recepcionista_data ['profissao'] );
		}
		if (isset( $recepcionista_data ['estado_civil'] )) {
			$recepcionista_update_vm->setEstadoCivil( $recepcionista_data ['estado_civil'] );
		}
		// if (isset($recepcionista_data['medicos'])) {
		// $recepcionista_update_vm->setIdMedico($recepcionista_data['medicos'] ?? []);
		// }

		if (isset( $recepcionista_data ['bairro'] )) {
			$recepcionista_update_vm->setBairro( $recepcionista_data ['bairro'] );
		}
		if (isset( $recepcionista_data ['cidade'] )) {
			$recepcionista_update_vm->setCidade( $recepcionista_data ['cidade'] );
		}
		if (isset( $recepcionista_data ['estado'] )) {
			$recepcionista_update_vm->setEstado( $recepcionista_data ['estado'] );
		}
		if (isset( $recepcionista_data ['logradouro'] )) {
			$recepcionista_update_vm->setLogradouro( $recepcionista_data ['logradouro'] );
		}
		
		if (isset( $recepcionista_data ['senha'] )) {
			if (strlen( trim( $recepcionista_data ['senha'] ) ) > 0) {
				$recepcionista_update_vm->setSenha( trim( $recepcionista_data ['senha'] ) );
			}
		}

		$recepcionista_update_vm->setIndicadoPor( JWTService::getTokenJWTPayload()->getUid() );
		$recepcionista_update_vm->setAlteradoPor( JWTService::getTokenJWTPayload()->getUid() );
		return $recepcionista_update_vm;

	}

	public static function getCepFromRecepcionistaUpdateVM(RecepcionistaUpdateViewModel $assistente_update_vm): CEP {

		$endereco = new CEP();
		if ($assistente_update_vm->getCep()) {
			$endereco->setCep( $assistente_update_vm->getCep() );
		}
		if ($assistente_update_vm->getLogradouro()) {
			$endereco->setLogradouro( $assistente_update_vm->getLogradouro() );
		}
		if ($assistente_update_vm->getCidade()) {
			$endereco->setCidade( $assistente_update_vm->getCidade() );
		}
		if ($assistente_update_vm->getEstado()) {
			$endereco->setEstado( $assistente_update_vm->getEstado() );
		}
		if ($assistente_update_vm->getBairro()) {
			$endereco->setBairro( $assistente_update_vm->getBairro() );
		}
		return $endereco;

	}

	public static function getEnderecoFromAssistenteUpdateVM(RecepcionistaUpdateViewModel $assistente_update_vm): Endereco {

		$endereco = new Endereco();
		if ($assistente_update_vm->getNumero()) {
			$endereco->setNumero( $assistente_update_vm->getNumero() );
		}
		if ($assistente_update_vm->getComplemento()) {
			$endereco->setComplemento( $assistente_update_vm->getComplemento() );
		}
		if ($assistente_update_vm->getReferencias()) {
			$endereco->setReferencias( $assistente_update_vm->getReferencias() );
		}
		return $endereco;

	}

	public static function getPessoaFromAssistenteUpdateVM(RecepcionistaUpdateViewModel $assistente_update_vm): Pessoa {

		$pessoa = new Pessoa();
		if ($assistente_update_vm->getTelefone1()) {
			$pessoa->setTelefone1( $assistente_update_vm->getTelefone1() );
		}
		if ($assistente_update_vm->getTelefone2()) {
			$pessoa->setTelefone2( $assistente_update_vm->getTelefone2() );
		}
		if ($assistente_update_vm->getAlteradoPor()) {
			$pessoa->setAlteradoPor( $assistente_update_vm->getAlteradoPor() );
		}
		return $pessoa;

	}

	public static function getPessoaFisicaFromAssistenteUpdateVM(RecepcionistaUpdateViewModel $assistente_update_vm): PessoaFisica {

		$pessoa_fisica = new PessoaFisica();
		if ($assistente_update_vm->getCpf()) {
			$pessoa_fisica->setCpf( $assistente_update_vm->getCpf() );
		}
		if ($assistente_update_vm->getRg()) {
			$pessoa_fisica->setRg( $assistente_update_vm->getRg() );
		}
		if ($assistente_update_vm->getGenero()) {
			$pessoa_fisica->setGenero( $assistente_update_vm->getGenero() );
		}
		if ($assistente_update_vm->getDataNascimento()) {
			$pessoa_fisica->setDataNascimento( $assistente_update_vm->getDataNascimento() );
		}
		if ($assistente_update_vm->getNome()) {
			$pessoa_fisica->setNome( $assistente_update_vm->getNome() );
		}
		if ($assistente_update_vm->getProfissao()) {
			$pessoa_fisica->setProfissao( $assistente_update_vm->getProfissao() );
		}
		if ($assistente_update_vm->getEstadoCivil()) {
			$pessoa_fisica->setEstadoCivil( $assistente_update_vm->getEstadoCivil() );
		}
		return $pessoa_fisica;

	}

	public static function getUsuarioFromAssistenteUpdateVM(RecepcionistaUpdateViewModel $assistente_update_vm): Usuario {

		$usuario = new Usuario();
		if ($assistente_update_vm->getFoto()) {
			$usuario->setFoto( $assistente_update_vm->getFoto() );
		}
		if ($assistente_update_vm->getAtivo()) {
			$usuario->setAtivo( $assistente_update_vm->getAtivo() );
		}
		if ($assistente_update_vm->getAlteradoPor()) {
			$usuario->setAlteradoPor( $assistente_update_vm->getAlteradoPor() );
		}
		return $usuario;

	}

	public static function getUsuarioPerfilFromAssistenteUpdateVM(RecepcionistaUpdateViewModel $recepcionista_update_vm): UsuarioPerfil {

		$usuario = new UsuarioPerfil();
		if ($recepcionista_update_vm->getPerfilId()) {
			$usuario->setIdPerfil( $recepcionista_update_vm->getPerfilId() );
		}
		return $usuario;

	}

	public static function getPacienteFromAssistenteUpdateVM(RecepcionistaUpdateViewModel $assistente_update_vm): Paciente {

		$paciente = new Paciente();
		if ($assistente_update_vm->getAlteradoPor()) {
			$paciente->setAlteradoPor( $assistente_update_vm->getAlteradoPor() );
		}
		if ($assistente_update_vm->getIndicadoPor()) {
			$paciente->setIndicadoPor( $assistente_update_vm->getIndicadoPor() );
		}
		return $paciente;

	}

	public static function getAssistenteMedicoFromAssistenteUpdateVM($value, Assistente $pessoa): AssistenteMedico {

		$profissional_clinica = AssistenteMedico::builder()->setIdASSISTENTE( $pessoa->getId() )
			->setIdMEDICO( $value )
			->build();
		return $profissional_clinica;

	}

}