<?php

namespace App\Services;

use App\ChameFacil\AuthBaseServiceCF;
use App\DAO\AssistenteDAO;
use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\Pagination\Pagination;
use App\DAO\RecepcaoDAO;
use App\Entities\Assistente\Assistente;
use App\Entities\Recepcao\Recepcionista;
use App\Mappers\AssistenteMapper;
use App\Mappers\RecepcaoMapper;
use App\Services\ServiceResponse\ServiceResponse;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\Utils\ResponseException;
use App\ViewModels\Assistente\AssistenteDetailsViewModel\AssistenteDetailsViewModel;
use App\ViewModels\Recepcao\RecepcaoRegistrationViewModel\RecepcaoRegistrationViewModel;
use App\ViewModels\Recepcao\RecepcionistaDetailsViewModel\RecepcionistaDetailsViewModel;
use GuzzleHttp\Client;

class RecepcaoService extends Service {

	public function registerRecepcionista(array $data): ServiceResponse {

		try {
			// $passwd = $this->generateRandomString(10);
			$passwd = $this->cript_password( $data ['senha'] );
			$data ['senha_chamefacil'] = $data ['senha'];
			$data ['senha'] = $passwd;
			$data ['token_confirmacao_email'] = '';
			$data ['ativo'] = 1;

			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
				$data ['foto'] = $dir . $new_name;
			}

			$recepcao_mapper = new RecepcaoMapper();
			$recepcionista_registration_vm = $recepcao_mapper->RecepcionistaRegistrationViewModelMapper( $data );
		} catch ( ResponseException $response_exception ) {
			$log_service = new LogService();
			$log_service->log_error( ServiceResponseInterface::SERVICE_INTERNAL_ERROR,
				'Ocorreu um erro durante o mapeamento da entidade RecepcaoRegistrationViewModel', $response_exception->getData() );
			return ServiceResponse::builder()->setStatus( ServiceResponseInterface::SERVICE_INTERNAL_ERROR )
				->setErrors( $response_exception->getData() )
				->build();
		}
		$recepcao_dao = new RecepcaoDAO();
		$dao_response = $recepcao_dao->persistRecepcionistaRegistrationVM( $recepcionista_registration_vm,
			function () use ($recepcionista_registration_vm, $passwd) {
				return $this->sendEmailConfirmationRegister( $recepcionista_registration_vm, $passwd );
			} );

		// Chame Facil
		$this->sendRecepcionistaChameFacil( $data );

		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				$recepcionista = (function (Recepcionista $recepcionista): Recepcionista {
					return $recepcionista;
				})( $dao_response->getData() );

				$service_response->setData( [ 
					'id_recepcionista' => $recepcionista->getId()
				] );
				break;
			case DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS :
				if (file_exists( $dir . $new_name ) === true) {
					unlink( $dir . $new_name );
				}
				break;
			case DAOResponseInterface::DUPLICATED_UNIQUE_KEY :
				$service_response->setStatus( ServiceResponseInterface::VALIDATION_PARAMS_ERROR );
				$service_response->setErrors( $dao_response->getErrors() );
				if (file_exists( $dir . $new_name ) === true) {
					unlink( $dir . $new_name );
				}
				break;
			case DAOResponseInterface::INTERNAL_DAO_ERROR :
				$service_response->setStatus( ServiceResponseInterface::SERVICE_INTERNAL_ERROR );
				if (file_exists( $dir . $new_name ) === true) {
					unlink( $dir . $new_name );
				}
				break;
			default :
				$service_response->setStatus( ServiceResponseInterface::DATABASE_CONNECTION_ERROR );
				if (file_exists( $dir . $new_name ) === true) {
					unlink( $dir . $new_name );
				}
				break;
		}
		return $service_response;

	}

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

		$recepcao_dao = new RecepcaoDAO();
		$dao_response = $recepcao_dao->getRecepcionistaList( $pagination, $query_filter_collection, $query_order_collection );
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response_status = ServiceResponseInterface::SUCESS;
				break;
			case DAOResponseInterface::RECORD_NOT_FOUND :
				$service_response_status = ServiceResponseInterface::RECORD_NOT_FOUND;
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				$service_response_status = ServiceResponseInterface::DATABASE_CONNECTION_ERROR;
				break;
		}
		$service_response = ServiceResponse::builder()->setStatus( $service_response_status )
			->build();
		if ($service_response_status === DAOResponseInterface::SUCESS) {
			$dao_response_data = $dao_response->getData();
			$recepcionista_details_array = RecepcaoMapper::getRecepcionistaDetailsArrayFromRecepcionistaDetailsVMList( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'recepcionistas' => $recepcionista_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

	private function sendEmailConfirmationRegister(RecepcaoRegistrationViewModel $recepcao_registration_vm, string $passwd): int {

		$email_service = new EmailService();
		$data = [ 
			'senha' => $passwd,
			'email' => $recepcao_registration_vm->getEmail()
		];
		$html_email = view( 'emails/assistente_registration', $data );
		$email_service_response = $email_service->send_email( $recepcao_registration_vm->getEmail(), 'Confirmação de email', $html_email );
		return $email_service_response->getStatus() === ServiceResponseInterface::SUCESS ? ServiceResponseInterface::SUCESS : ServiceResponseInterface::SERVICE_INTERNAL_ERROR;

	}

	public function updateRecepcionistaData(int $id_recepcionista, array $data): ServiceResponse {

		try {
			$recepcionista_update_vm = RecepcaoMapper::getRecepcionistaUpdateVMFromArray( $data );
			if (count( $recepcionista_update_vm->toArray( true ) ) === 0) {
				return ServiceResponse::builder()->setStatus( ServiceResponseInterface::INSUFFICIENT_DATA )
					->build();
			}
		} catch ( ResponseException $response_exception ) {
			$log_service = new LogService();
			$log_service->log_error( ServiceResponseInterface::SERVICE_INTERNAL_ERROR,
				'Ocorreu um erro durante o mapeamento da entidade RecepcionistaUpdateViewModel', $response_exception->getData() );
			return ServiceResponse::builder()->setStatus( ServiceResponseInterface::SERVICE_INTERNAL_ERROR )
				->setErrors( $response_exception->getData() )
				->build();
		}

		$unidades = $data ['unidades'];
		$clinicas = array_unique( explode( ",", $unidades ) );

		$recepcao_dao = new RecepcaoDAO();
		$image = $recepcao_dao->getImageAssistente( $id_recepcionista );
		$dao_response = $recepcao_dao->persistRecepcionistaUpdateVM( $id_recepcionista, $recepcionista_update_vm );
		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				// gravar as unidades
				$this->updateClinicasByRecepcionista( $id_recepcionista, $clinicas );
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				if (file_exists( $image ) === true) {
					unlink( $image );
				}
				break;
			case DAOResponseInterface::DUPLICATED_UNIQUE_KEY :
				if (file_exists( $recepcionista_update_vm->getFoto() ) === true) {
					unlink( $recepcionista_update_vm->getFoto() );
				}
				break;
			case DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS :
				$service_response->setStatus( ServiceResponseInterface::VALIDATION_PARAMS_ERROR );
				$service_response->setErrors( $dao_response->getErrors() );
				if (file_exists( $recepcionista_update_vm->getFoto() ) === true) {
					unlink( $recepcionista_update_vm->getFoto() );
				}
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				$service_response->setStatus( ServiceResponseInterface::DATABASE_CONNECTION_ERROR );
				if (file_exists( $recepcionista_update_vm->getFoto() ) === true) {
					unlink( $recepcionista_update_vm->getFoto() );
				}
				break;
		}
		return $service_response;

	}

	public function getRecepcionista(QueryFilter $query_filter): ServiceResponse {

		$recepcao_dao = new RecepcaoDAO();
		$query_filter_collection = new QueryFilterCollection();
		$query_filter_collection->push( $query_filter );
		// $array_response = $recepcao_dao->getMedicosFromAssistenteList($query_filter->getValue());
		$dao_response = $recepcao_dao->getRecepcionista( $query_filter_collection );
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response_status = ServiceResponseInterface::SUCESS;
				break;
			case DAOResponseInterface::RECORD_NOT_FOUND :
				$service_response_status = ServiceResponseInterface::RECORD_NOT_FOUND;
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				$service_response_status = ServiceResponseInterface::DATABASE_CONNECTION_ERROR;
				break;
		}
		$service_response = ServiceResponse::builder()->setStatus( $service_response_status )
			->build();
		if ($service_response_status === DAOResponseInterface::SUCESS) {
			$recepcionista_details_vm = (function (RecepcionistaDetailsViewModel $recepcionista_details_vm): RecepcionistaDetailsViewModel {
				return $recepcionista_details_vm;
			})( $dao_response->getData() );
			// $recepcionista_details_vm->setMedicos($array_response);
			$data = $recepcionista_details_vm->toArray();
			$unidade_service_response = (new UnidadeService())->getUnidadeListByUsuario( null, null, null, $data ['id_usuario'] );
			$data = array_merge( $data, $unidade_service_response->getData() );
			$service_response->setData( $data );
		}
		return $service_response;

	}

	private function sendRecepcionistaChameFacil(array $recepcionista) {

		$auth_chamefacil = new AuthBaseServiceCF();
		$credenciais_chamefacil = $auth_chamefacil->authBaseService();

		$client = new Client();
		$result = $client->post( 'http://chamefacilpettree.prolins.com.br/api/usuario/Adicionar',
			[ 
				'headers' => [ 
					'token' => $credenciais_chamefacil->Token
				],
				'json' => [ 
					"Codigo" => 0,
					"Nome" => $recepcionista ['nome'],
					"Login" => $recepcionista ['email'],
					"Senha" => $recepcionista ['senha_chamefacil'],
					"CodigoPerfil" => 2,
					"Cadastro" => date( 'Y-m-d H:i:s' ),
					"Ativo" => 1,
					"Email" => $recepcionista ['email'],
					"TokenPushRequest" => ""
				]
			] );
		return $result->getBody()
			->getContents();

	}

	private function updateClinicasByRecepcionista(int $id_assistente, array $data) {

		if (count( $data ) > 0) {
			$profissionalService = new ProfissionalService();
			$profissionalService_response = $profissionalService->getIdProfissionalByAssistenteId( $id_assistente );
			if ($profissionalService_response->getStatus() == ServiceResponseInterface::SUCESS) {
				$dados = $profissionalService_response->getData();
				$idProfissional = $dados [0] ['id_profissional'];
				$profissionalClienicaService = new ProfissionalClinicaService();
				$profissionalClienicaService_response = $profissionalClienicaService->getClinicasByProfissionalId( $idProfissional );
				if ($profissionalClienicaService_response->getStatus() == ServiceResponseInterface::SUCESS) {
					$resposta = $profissionalClienicaService_response->getData();
					$minhas_clinicas = array ();
					for($y = 0; $y < count( $resposta ); $y++) {
						array_push( $minhas_clinicas, $resposta [$y] ['is_unidade'] );
					}
					// alterar estrutura de minhas clinicas.
					$excluir = array_values( array_diff( $minhas_clinicas, array_values( $data ) ) );
					$incluir = array_values( array_diff( array_values( $data ), $minhas_clinicas ) );

					for($i = 0; $i < count( $incluir ); $i++) {
						if (intval( $incluir [$i] ) > 0) {
							$incluir_response = $profissionalClienicaService->incluirProfissionalClinica( $idProfissional, intval( $incluir [$i] ) );
						}
					}

					for($i = 0; $i < count( $excluir ); $i++) {
						if (intval( $excluir [$i] ) > 0) {
							$excluir_response = $profissionalClienicaService->excluirProfissionalClinica( $idProfissional, intval( $excluir [$i] ) );
						}
					}
				}
				if ($profissionalClienicaService_response->getStatus() == ServiceResponseInterface::RECORD_NOT_FOUND) {

					for($i = 0; $i < count( $data ); $i++) {
						if (intval( $data [$i] ) > 0) {
							$incluir_response = $profissionalClienicaService->incluirProfissionalClinica( $idProfissional, intval( $data [$i] ) );
						}
					}
				}
			}
		}

	}

}