<?php

namespace App\Mappers;

// use App\Entities\AdministrativoMedico\AdministrativoMedico;
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\Services\JWTService;
use App\Utils\Collections\GeneralCollection;
use App\Utils\DateUtils;
use App\ViewModels\Administrativo\AdministrativoDetailsViewModel\AdministrativoDetailsViewModel;
use App\ViewModels\Administrativo\AdministrativoRegistrationViewModel\AdministrativoRegistrationViewModel;
use App\ViewModels\Administrativo\AdministrativoUpdateViewModel\AdministrativoUpdateViewModel;
use App\DAO\AdministrativoDAO;

class AdministrativoMapper {

	public static function AdministrativoRegistrationViewModelMapper(array $administrativo): AdministrativoRegistrationViewModel {

		$jwt_payload = JWTService::getTokenJWTPayload();
		$uid = $jwt_payload ? $jwt_payload->getUid() : null;
		$administrativo_registration_vm = AdministrativoRegistrationViewModel::builder()->setFoto( $administrativo ['foto'] )
			->setNome( $administrativo ['nome'] )
			->setEmail( $administrativo ['email'] )
			->setRg( $administrativo ['rg'] )
			->setGenero( $administrativo ['genero'] )
			->setDataNascimento( $administrativo ['data_nascimento'] )
			->setEstadoCivil( $administrativo ['estado_civil'] )
			->setCep( $administrativo ['cep'] )
			->setNumero( $administrativo ['numero'] )
			->setComplemento( $administrativo ['complemento'] )
			->setReferencias( $administrativo ['referencias'] )
			->setCpf( $administrativo ['cpf'] )
			->setTelefone1( $administrativo ['telefone_1'] )
			->setTelefone2( $administrativo ['telefone_2'] )
			->setAdicionadoPor( $uid )
			->setProfissao( $administrativo ['profissao'] )
			->setIndicadoPor( $uid )
			->setSenha( $administrativo ['senha'] )
			->setAtivo( $administrativo ['ativo'] )
			->setTokenConfirmacaoEmail( $administrativo ['token_confirmacao_email'] )
			->setIdMedico( 0 )
			->setIdPerfil( $administrativo ['id_perfil'] )
			->setCidade( $administrativo ['cidade'] )
			->setEstado( $administrativo ['estado'] )
			->setBairro( $administrativo ['bairro'] )
			->setLogradouro( $administrativo ['logradouro'] )
			->setIdClinica( $administrativo ['id_clinica'] )
			->build();
		return $administrativo_registration_vm;

	}

	public static function getAdministrativoListVMFromArray(array $administrativo): AdministrativoDetailsViewModel {

		$administrativo_details_vm = AdministrativoDetailsViewModel::builder()->setId( $administrativo ['id'] )
			->setCpf( $administrativo ['cpf'] )
			->setRg( $administrativo ['rg'] )
			->setNome( $administrativo ['nome'] )
			->setGenero( $administrativo ['genero'] )
			->setDataNascimento( $administrativo ['data_nascimento'] )
			->setTelefone1( $administrativo ['telefone_1'] )
			->setTelefone2( $administrativo ['telefone_2'] )
			->setCep( $administrativo ['cep'] )
			->setNumero( $administrativo ['numero'] )
			->setComplemento( $administrativo ['complemento'] )
			->setReferencias( $administrativo ['referencias'] )
			->setEstado( $administrativo ['estado'] )
			->setCidade( $administrativo ['cidade'] )
			->setBairro( $administrativo ['bairro'] )
			->setLogradouro( $administrativo ['logradouro'] )
			->setEmail( $administrativo ['email'] )
			->setFoto( "" )
			->setAtivo( $administrativo ['ativo'] )
			->setProfissao( $administrativo ['profissao'] )
			->setEstadoCivil( $administrativo ['estado_civil'] )
			->setIdClinica( $administrativo ['id_clinica'] )
			->setNomeFantasia( $administrativo ['nome_fantasia'] )
			->setDescricaoPerfil( $administrativo ['descricao_perfil'] )
			->setIdPerfil( $administrativo ['id_perfil'] )
			->build();
		return $administrativo_details_vm;

	}

	public static function getAdministrativoDetailsVMFromArray(array $administrativo): AdministrativoDetailsViewModel {

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

		$adm_unidades = new AdministrativoDAO();
		$response_unidades = $adm_unidades->getUnidadesAdministrativo( $administrativo ['id'] );

		$administrativo_details_vm = AdministrativoDetailsViewModel::builder()->setId( $administrativo ['id'] )
			->setCpf( $administrativo ['cpf'] )
			->setRg( $administrativo ['rg'] )
			->setNome( $administrativo ['nome'] )
			->setGenero( $administrativo ['genero'] )
			->setDataNascimento( $administrativo ['data_nascimento'] )
			->setTelefone1( $administrativo ['telefone_1'] )
			->setTelefone2( $administrativo ['telefone_2'] )
			->setCep( $administrativo ['cep'] )
			->setNumero( $administrativo ['numero'] )
			->setComplemento( $administrativo ['complemento'] )
			->setReferencias( $administrativo ['referencias'] )
			->setEstado( $administrativo ['estado'] )
			->setCidade( $administrativo ['cidade'] )
			->setBairro( $administrativo ['bairro'] )
			->setLogradouro( $administrativo ['logradouro'] )
			->setEmail( $administrativo ['email'] )
			->setFoto( $filebase64 ?? [ ])
			->setAtivo( $administrativo ['ativo'] )
			->setAtivoDescricao( $administrativo ['ativo_desc'] ?? '-')
			->setProfissao( $administrativo ['profissao'] )
			->setEstadoCivil( $administrativo ['estado_civil'] )
			->setIdClinica( $response_unidades )
			->setNomeFantasia( $administrativo ['nome_fantasia'] )
			->setDescricaoPerfil( $administrativo ['descricao_perfil'] )
			->setIdPerfil( $administrativo ['id_perfil'] )
			->setTipo( $ext )
			->build();
		return $administrativo_details_vm;

	}

	public static function getAdministrativoDetailsVMListFromArray(array $administrativo_list): GeneralCollection {

		$administrativo_details_vm_collection = new GeneralCollection();
		for($i = 0, $number_administrativos = count( $administrativo_list ); $i < $number_administrativos; $i++) {
			$administrativo_details_vm_collection->push( AdministrativoMapper::getAdministrativoListVMFromArray( $administrativo_list [$i] ) );
		}
		return $administrativo_details_vm_collection;

	}

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

		return $paciente_details_vm_collection->toArray();

	}

	public static function getCepFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm): CEP {

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

	}

	public static function getEnderecoFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, CEP $cep): Endereco {

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

	}

	public static function getPessoaFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, Endereco $endereco): Pessoa {

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

	}

	public static function getPessoaFisicaFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, Pessoa $pessoa): PessoaFisica {

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

	}

	public static function getUsuarioFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, Pessoa $pessoa): Usuario {

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

	}

	public static function getPacienteFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, Pessoa $pessoa): Paciente {

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

	}

	public static function getClienteFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, Pessoa $pessoa): Cliente {

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

	}

	public static function getConfirmacaoEmailFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm,
			Usuario $usuario): ConfirmacaoEmail {

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

	}

	public static function getUsuarioPerfilFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm,
			Usuario $usuario): UsuarioPerfil {

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

	}

	public static function getProfissionalFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm, Pessoa $pessoa): Profissional {

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

	}

	public static function getProfissionalClinicaFromProfissionalClinicaRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm,
			Profissional $pessoa, $unidade): ProfissionalClinica {

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

	}

	public static function getAdministrativoFromAdministrativoRegistrationVM(AdministrativoRegistrationViewModel $administrativo_registration_vm,
			Profissional $pessoa): Administrativo {

		$administrativo = Administrativo::builder()->setIdProfissional( $pessoa->getId() )
			->build();
		return $administrativo;

	}

	public static function getAdministrativoUpdateVMFromArray(array $administrativo_data): AdministrativoUpdateViewModel {

		$administrativo_update_vm = new AdministrativoUpdateViewModel();
		if (isset( $administrativo_data ['cpf'] )) {
			$administrativo_update_vm->setCpf( $administrativo_data ['cpf'] );
		}
		if (isset( $administrativo_data ['rg'] )) {
			$administrativo_update_vm->setRg( $administrativo_data ['rg'] );
		}
		if (isset( $administrativo_data ['nome'] )) {
			$administrativo_update_vm->setNome( $administrativo_data ['nome'] );
		}
		if (isset( $administrativo_data ['ativo'] )) {
			$administrativo_update_vm->setAtivo( $administrativo_data ['ativo'] );
		}
		if (isset( $administrativo_data ['genero'] )) {
			$administrativo_update_vm->setGenero( $administrativo_data ['genero'] );
		}
		if (isset( $administrativo_data ['data_nascimento'] )) {
			$administrativo_update_vm->setDataNascimento( $administrativo_data ['data_nascimento'] );
		}
		if (isset( $administrativo_data ['telefone_1'] )) {
			$administrativo_update_vm->setTelefone1( $administrativo_data ['telefone_1'] );
		}
		if (isset( $administrativo_data ['telefone_2'] )) {
			$administrativo_update_vm->setTelefone2( $administrativo_data ['telefone_2'] );
		}
		if (isset( $administrativo_data ['cep'] )) {
			$administrativo_update_vm->setCep( $administrativo_data ['cep'] );
		}
		if (isset( $administrativo_data ['numero'] )) {
			$administrativo_update_vm->setNumero( $administrativo_data ['numero'] );
		}
		if (isset( $administrativo_data ['complemento'] )) {
			$administrativo_update_vm->setComplemento( $administrativo_data ['complemento'] );
		}
		if (isset( $administrativo_data ['referencias'] )) {
			$administrativo_update_vm->setReferencias( $administrativo_data ['referencias'] );
		}
		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
			$administrativo_data ['foto'] = $dir . $new_name;
		}

		if (isset( $administrativo_data ['foto'] )) {
			$administrativo_update_vm->setFoto( $administrativo_data ['foto'] );
		}
		if (isset( $administrativo_data ['profissao'] )) {
			$administrativo_update_vm->setProfissao( $administrativo_data ['profissao'] );
		}
		if (isset( $administrativo_data ['estado_civil'] )) {
			$administrativo_update_vm->setEstadoCivil( $administrativo_data ['estado_civil'] );
		}
		if (isset( $administrativo_data ['id_medico'] )) {
			$administrativo_update_vm->setIdMedico( $administrativo_data ['id_medico'] );
		}

		if (isset( $administrativo_data ['id_clinica'] )) {
			$administrativo_update_vm->setIdClinica( $administrativo_data ['id_clinica'] );
		}

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

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

	}

	public static function getCepFromAdministrativoUpdateVM(AdministrativoUpdateViewModel $administrativo_update_vm): CEP {

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

	}

	public static function getEnderecoFromAdministrativoUpdateVM(AdministrativoUpdateViewModel $administrativo_update_vm): Endereco {

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

	}

	public static function getPessoaFromAdministrativoUpdateVM(AdministrativoUpdateViewModel $administrativo_update_vm): Pessoa {

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

	}

	public static function getPessoaFisicaFromAdministrativoUpdateVM(AdministrativoUpdateViewModel $administrativo_update_vm): PessoaFisica {

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

	}

	public static function getUsuarioFromAdministrativoUpdateVM(AdministrativoUpdateViewModel $administrativo_update_vm): Usuario {

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

	}

	public static function getPacienteFromAdministrativoUpdateVM(AdministrativoUpdateViewModel $administrativo_update_vm): Paciente {

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

	}

	public static function getProfissionalClinicaFromProfissionalClinicaUpdateVM(AdministrativoUpdateViewModel $administrativo_update_vm): ProfissionalClinica {

		$profissional_clinica = ProfissionalClinica::builder()->
		// ->setIdProfissional($pessoa->getId())
		setIdPessoaJuridica( $administrativo_update_vm->getIdClinica() )
			->build();
		return $profissional_clinica;

	}

}
