<?php

namespace App\Mappers;

use App\Entities\Agendamento\Agendamento;
use App\Entities\AgendamentoPet\AgendamentoPet;
use App\Services\JWT\JWTPayload\JWTPayloadBuilder;
use App\Services\JWTService;
use App\Utils\Collections\GeneralCollection;
use App\Utils\DateUtils;
use App\Utils\ResponseException;
use App\ViewModels\Agendamento\AgendamentoDetailsViewModel\AgendamentoDetailsViewModel;
use App\ViewModels\Agendamento\AgendamentoInfoViewModel\AgendamentoInfoViewModel;
use App\ViewModels\Agendamento\AgendamentoRegistrationViewModel\AgendamentoRegistrationViewModel;
use App\ViewModels\Agendamento\AgendamentoUpdateViewModel\AgendamentoUpdateViewModel;
use Firebase\JWT\JWT;

class AgendamentoMapper {

	public static function getAgendamentoRegistrationVMFromArray(array $data): AgendamentoRegistrationViewModel {

		$agendamento_registration_vm = AgendamentoRegistrationViewModel::builder()->setIdAgenda( $data ['id_agenda'] )
			->setIdCliente( $data ['id_cliente'] )
			->setIdPaciente( $data ['id_paciente'] )
			->setIdProcedimento( $data ['id_procedimento'] )
			->setIdPet( $data ['id_pet'] )			
			->setAdicionadoPor( JWTService::getTokenJWTPayload()->getUid() )
			->build();
		return $agendamento_registration_vm;

	}

	public static function getAgendamentoRegistrationVMFromAnamneeseAdicional(array $data): AgendamentoRegistrationViewModel {
		
		$agendamento_registration_vm = AgendamentoRegistrationViewModel::builder()->setIdAgenda( $data ['id_agenda'] )
		->setIdCliente( $data ['id_cliente'] )
		->setIdPaciente( $data ['id_paciente'] )
		->setIdProcedimento( $data ['id_procedimento'] )
		->setIdPet( $data ['id_pet'] )
		->setIdRequisicao($data ['id_requisicao'])
		->setAdicionadoPor( JWTService::getTokenJWTPayload()->getUid() )
		->build();
		return $agendamento_registration_vm;
		
	}
	
	
	
	public static function getAgendamentoFromAgendamentoRegistrationVM(AgendamentoRegistrationViewModel $agendamento_registration_vm): Agendamento {

		$codigo = $agendamento_registration_vm->getIdAgenda();
		$agendamento = Agendamento::builder()->setIdCliente( $agendamento_registration_vm->getIdCliente() )
			->setIdPaciente( $agendamento_registration_vm->getIdPaciente() )
			->setIdRequisicao( $agendamento_registration_vm->getIdRequisicao() )
			->setIdProcedimento( $agendamento_registration_vm->getIdProcedimento() )
			->setIdAgenda( $agendamento_registration_vm->getIdAgenda() )
			->setCodigo( $codigo )
			->setCanceladoEm( '' )
			->setAdicionadoPor( $agendamento_registration_vm->getAdicionadoPor() )
			->build();
		return $agendamento;

	}

	public static function getAgendamentoPetFromAgendamentoRegistrationVM(AgendamentoRegistrationViewModel $agendamento_registration_vm,
			Agendamento $agendamento): AgendamentoPet {

		$codigo = $agendamento_registration_vm->getIdAgenda();
		$agendamento = AgendamentoPet::builder()->setIdPet( $agendamento_registration_vm->getIdPet() )
			->setIdAgendamento( $agendamento->getId() )
			->build();
		return $agendamento;

	}

	public static function getAgendamentoUpdateVMFromArray(array $data): AgendamentoUpdateViewModel {

		$agendamento_update_vm = AgendamentoUpdateViewModel::builder()->setAtrasado( $data ['atrasado'] )
			->setIdPaciente( $data ['id_paciente'] )
			->setIdProcedimento( $data ['id_procedimento'] )
			->setIdCliente( $data ['id_cliente'] )
			->setIdAgenda( $data ['id_agenda'] )
			->build();
		if (count( $agendamento_update_vm->toArray( true ) ) === 0) {
			throw new ResponseException( [ ], 'Dados insuficientes para fazer a atualização.' );
		} else {
			return $agendamento_update_vm;
		}

	}

	public static function getAgendamentoFromAgendamentoUpdateVM(AgendamentoUpdateViewModel $agendamento_update_vm): Agendamento {

		$agendamento = new Agendamento();
		if ($agendamento_update_vm->getIdAgenda() !== null) {
			$agendamento->setIdAgenda( $agendamento_update_vm->getIdAgenda() );
			$agendamento->setCodigo( ( string ) $agendamento_update_vm->getIdAgenda() );
		}
		if ($agendamento_update_vm->getIdProcedimento() !== null) {
			$agendamento->setIdProcedimento( $agendamento_update_vm->getIdProcedimento() );
		}
		if ($agendamento_update_vm->getIdRequisicao() !== null) {
			$agendamento->setIdRequisicao( $agendamento_update_vm->getIdRequisicao() );
		}
		if ($agendamento_update_vm->getIdPaciente() !== null) {
			$agendamento->setIdPaciente( $agendamento_update_vm->getIdPaciente() );
		}
		if ($agendamento_update_vm->getIdCliente() !== null) {
			$agendamento->setIdCliente( $agendamento_update_vm->getIdCliente() );
		}
		if ($agendamento_update_vm->getAtrasado() !== null) {
			$agendamento->setAtrasado( $agendamento_update_vm->getAtrasado() );
		}
		$jwt_payload = JWTService::getTokenJWTPayload();
		$agendamento->setAlteradoPor( $jwt_payload->getUid() );
		$agendamento->setAlteradoEm( DateUtils::now() );
		return $agendamento;

	}

	public static function getAgendamentoInfoVMFromArray(array $response_array): AgendamentoInfoViewModel {

		return AgendamentoInfoViewModel::builder()->setIdAgenda( $response_array ['id_agenda'] )
			->setIdCliente( $response_array ['id_cliente'] )
			->setIdPaciente( $response_array ['id_paciente'] )
			->setIdConsulta( $response_array ['id_consulta'] )
			->setIdUsuario( $response_array ['id_usuario'] )
			->build();

	}

	# ---------------------------------------------------------------------------------------------------------------#
	public static function getAgendamentoDetailsVMFromArray(array $agendamento): AgendamentoDetailsViewModel {

		$agendamento_details_vm = AgendamentoDetailsViewModel::builder()->setIdProcedimento( $agendamento ['id_procedimento'] )
			->setIdAgendamento( $agendamento ['id_agendamento'] )
			->setIdPaciente( $agendamento ['id_paciente'] )
			->setIdRequisicao( $agendamento ['id_requisicao'] ?? 0)
			->setDescricaoTipoProcedimento( $agendamento ['descricao_tipo_procedimento'] )
			->setDescricaoProcedimento( $agendamento ['descricao_procedimento'] )
			->setData( $agendamento ['data'] )
			->setHoraInicio( $agendamento ['hora_inicio'] )
			->setHoraFinal( $agendamento ['hora_final'] )
			->setCodigo( $agendamento ['codigo'] )
			->setCpf( $agendamento ['cpf'] )
			->setRg( $agendamento ['rg'] )
			->setNome( $agendamento ['nome'] )
			->setGenero( $agendamento ['genero'] )
			->setDataNascimento( $agendamento ['data_nascimento'] )
			->setTelefone1( $agendamento ['telefone_1'] )
			->setTelefone2( $agendamento ['telefone_2'] )
			->setCep( $agendamento ['cep'] )
			->setNumero( $agendamento ['numero'] )
			->setComplemento( $agendamento ['complemento'] )
			->setReferencias( $agendamento ['referencias'] )
			->setEstado( $agendamento ['estado'] )
			->setCidade( $agendamento ['cidade'] )
			->setBairro( $agendamento ['bairro'] )
			->setLogradouro( $agendamento ['logradouro'] )
			->setEmail( $agendamento ['email'] )
			->setFoto( $agendamento ['foto'] )
			->setAtivo( $agendamento ['ativo'] )
			->setProfissao( $agendamento ['profissao'] )
			->setEstadoCivil( $agendamento ['estado_civil'] )
			->build();
		return $agendamento_details_vm;

	}

	public static function getAgendamentoDetailsVMListFromArray(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( AgendamentoMapper::getAgendamentoDetailsVMFromArray( $assistente_list [$i] ) );
		}
		return $assistente_details_vm_collection;

	}

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

		return $paciente_details_vm_collection->toArray();

	}

	# ---------------------------------------------------------------------------------------------------------------#
}