<?php

namespace App\Mappers;

use App\DAO\UnidadeDAO;
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\Services\JWTService;
use App\Utils\Collections\GeneralCollection;
use App\Utils\DateUtils;
use App\ViewModels\Assistente\AssistenteDetailsViewModel\AssistenteDetailsViewModel;
use App\ViewModels\Assistente\AssistenteRegistrationViewModel\AssistenteRegistrationViewModel;
use App\ViewModels\Assistente\AssistenteUpdateViewModel\AssistenteUpdateViewModel;

class AssistenteMapper {

	public static function AssistenteRegistrationViewModelMapper(array $assistente): AssistenteRegistrationViewModel {

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

	}

	public static function getAssistenteListVMFromArray(array $assistente): AssistenteDetailsViewModel {

		$assistente_details_vm = AssistenteDetailsViewModel::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 ['id_perfil'] )
			->setPerfilDescricao( $assistente ['perfil_descricao'] )
			->build();
		return $assistente_details_vm;

	}

	public static function getAssistenteDetailsVMFromArray(array $assistente): AssistenteDetailsViewModel {

		if (file_exists( $assistente ['foto'] ) === true) {
			$get_file = file_get_contents( $assistente ['foto'] );
			$ext = pathinfo( $assistente ['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 );
		}

		$assistente_details_vm = AssistenteDetailsViewModel::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( $filebase64 ?? [ ])
			->setAtivo( $assistente ['ativo'] )
			->setAtivoDescricao( $assistente ['ativo_desc'] ?? '-')
			->setProfissao( $assistente ['profissao'] ?? '-')
			->setEstadoCivil( $assistente ['estado_civil'] )
			->setPerfilId( $assistente ['perfil_id'] )
			->setPerfilDescricao( $assistente ['perfil_descricao'] )
			->setIdUsuario( $assistente ['id_usuario'] )
			->setTipo( $ext )
			->build();
		return $assistente_details_vm;

	}

	public static function getAssistenteDetailsVMListFromArray(array $assistente_list): GeneralCollection {

		$assistente_details_vm_collection = new GeneralCollection();
		for($i = 0, $number_assistentes = count( $assistente_list ); $i < $number_assistentes; $i++) {
			$assistente_details_vm_collection->push( AssistenteMapper::getAssistenteListVMFromArray( $assistente_list [$i] ) );
		}
		return $assistente_details_vm_collection;

	}

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

		return $paciente_details_vm_collection->toArray();

	}

	public static function getCepFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm): CEP {

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

	}

	public static function getEnderecoFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, CEP $cep): Endereco {

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

	}

	public static function getPessoaFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Endereco $endereco): Pessoa {

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

	}

	public static function getPessoaFisicaFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Pessoa $pessoa): PessoaFisica {

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

	}

	public static function getUsuarioFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Pessoa $pessoa): Usuario {

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

	}

	public static function getPacienteFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Pessoa $pessoa): Paciente {

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

	}

	public static function getClienteFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Pessoa $pessoa): Cliente {

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

	}

	public static function getConfirmacaoEmailFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Usuario $usuario): ConfirmacaoEmail {

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

	}

	public static function getUsuarioPerfilFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Usuario $usuario): UsuarioPerfil {

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

	}

	public static function getProfissionalFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Pessoa $pessoa): Profissional {

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

	}

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

		$profissional_clinica = ProfissionalClinica::builder()->setIdPROFISSIONAL( $pessoa->getId() )
			->setIdPessoaJuridica( ID_CLINICA_NESTOR )
			->build();
		return $profissional_clinica;

	}

	public static function getAssistenteFromAssistenteRegistrationVM(AssistenteRegistrationViewModel $assistente_registration_vm, Profissional $pessoa): Assistente {

		$assistente = Assistente::builder()->setIdProfissional( $pessoa->getId() )
			->build();
		return $assistente;

	}

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

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

	}

	public static function getAssistenteUpdateVMFromArray(array $assistente_data): AssistenteUpdateViewModel {

		$assistente_update_vm = new AssistenteUpdateViewModel();
		if (isset( $assistente_data ['cpf'] )) {
			$assistente_update_vm->setCpf( $assistente_data ['cpf'] );
		}
		if (isset( $assistente_data ['rg'] )) {
			$assistente_update_vm->setRg( $assistente_data ['rg'] );
		}
		if (isset( $assistente_data ['nome'] )) {
			$assistente_update_vm->setNome( ucwords( $assistente_data ['nome'] ) );
		}
		if (isset( $assistente_data ['ativo'] )) {
			$ativo = ( int ) $assistente_data ['ativo'];
			$assistente_update_vm->setAtivo( $ativo );
		}
		if (isset( $assistente_data ['genero'] )) {
			$assistente_update_vm->setGenero( $assistente_data ['genero'] );
		}
		if (isset( $assistente_data ['data_nascimento'] )) {
			$assistente_update_vm->setDataNascimento( $assistente_data ['data_nascimento'] );
		}
		if (isset( $assistente_data ['telefone_1'] )) {
			$assistente_update_vm->setTelefone1( $assistente_data ['telefone_1'] );
		}
		if (isset( $assistente_data ['telefone_2'] )) {
			$assistente_update_vm->setTelefone2( $assistente_data ['telefone_2'] );
		}
		if (isset( $assistente_data ['telefone_3'] )) {
			$assistente_update_vm->setTelefone3( $assistente_data ['telefone_3'] ?? '');
		}
		if (isset( $assistente_data ['cep'] )) {
			$assistente_update_vm->setCep( $assistente_data ['cep'] );
		}
		if (isset( $assistente_data ['numero'] )) {
			$assistente_update_vm->setNumero( $assistente_data ['numero'] );
		}
		if (isset( $assistente_data ['complemento'] )) {
			$assistente_update_vm->setComplemento( $assistente_data ['complemento'] );
		}
		if (isset( $assistente_data ['referencias'] )) {
			$assistente_update_vm->setReferencias( $assistente_data ['referencias'] );
		}
		if (isset( $assistente_data ['id_perfil'] )) {
			$assistente_update_vm->setPerfilId( $assistente_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
			$assistente_data ['foto'] = $dir . $new_name;
		}

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

		if (isset( $assistente_data ['bairro'] )) {
			$assistente_update_vm->setBairro( $assistente_data ['bairro'] );
		}
		if (isset( $assistente_data ['cidade'] )) {
			$assistente_update_vm->setCidade( $assistente_data ['cidade'] );
		}
		if (isset( $assistente_data ['estado'] )) {
			$assistente_update_vm->setEstado( $assistente_data ['estado'] );
		}
		if (isset( $assistente_data ['logradouro'] )) {
			$assistente_update_vm->setLogradouro( $assistente_data ['logradouro'] );
		}

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

	}

	public static function getCepFromAssistenteUpdateVM(AssistenteUpdateViewModel $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(AssistenteUpdateViewModel $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(AssistenteUpdateViewModel $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(AssistenteUpdateViewModel $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(AssistenteUpdateViewModel $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(AssistenteUpdateViewModel $assistente_update_vm): UsuarioPerfil {

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

	}

	public static function getPacienteFromAssistenteUpdateVM(AssistenteUpdateViewModel $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;

	}

}