<?php

namespace App\Services;

use App\ChameFacil\AuthBaseServiceCF;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\FormularioDAO;
use App\DAO\MedicoDAO;
use App\DAO\Pagination\Pagination;
use App\Mappers\FormularioMapper;
use App\Mappers\MedicoMapper;
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\Medico\MedicoDetailsViewModel\MedicoDetailsViewModel;
use App\ViewModels\Medico\MedicoRegistrationViewModel\MedicoRegistrationViewModel;
use GuzzleHttp\Client;
use Kint\Parser\SerializePlugin;

// use phpDocumentor\Reflection\DocBlock\Tags\Var_;
class MedicoService extends Service {

	public function getMedicoIDFromUsuarioID(int $id_usuario): int {

		$medico_dao = new MedicoDAO();
		$dao_response = $medico_dao->getMedicoIDFromUsuarioID( $id_usuario );
		$id_medico = $dao_response->getStatus() === DAOResponseInterface::SUCESS ? ( int ) $dao_response->getData() : 0;
		return $id_medico;

	}

	public function getMedico(QueryFilter $query_filter): ServiceResponse {

		$assistente_dao = new MedicoDAO();
		$query_filter_collection = new QueryFilterCollection();
		$query_filter_collection->push( $query_filter );
		$dao_response = $assistente_dao->getMedico( $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) {
			$assistente_details_vm = (function (MedicoDetailsViewModel $assistente_details_vm): MedicoDetailsViewModel {
				return $assistente_details_vm;
			})( $dao_response->getData() );
			$service_response->setData( $assistente_details_vm->toArray() );
		}
		return $service_response;

	}

	public function registerMedico(array $data): ServiceResponse {

		try {
			$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;
			}

			if (isset( $data ['assinatura'] )) {
				$encoded_string = $data ['assinatura'];
				$target_dir = '../writable/assinatura/';

				$mime_type = finfo_buffer( finfo_open(), $encoded_string, FILEINFO_MIME_TYPE ); // extract mime type
				$extension = $this->mime2ext( $mime_type ); // extract extension from mime type
				$file = uniqid() . '.' . $extension; // rename file as a unique name
				$file_dir = $target_dir . uniqid() . '.' . $extension;
				file_put_contents( $file_dir, $encoded_string );
				header( 'Content-Type: application/json' );
			}

			$assistente_registration_vm = MedicoMapper::MedicoRegistrationViewModelMapper( $data, $file_dir );
		} catch ( ResponseException $response_exception ) {
			$log_service = new LogService();
			$log_service->log_error( ServiceResponseInterface::SERVICE_INTERNAL_ERROR,
				'Ocorreu um erro durante o mapeamento da entidade MedicoRegistrationViewModel', $response_exception->getData() );
			return ServiceResponse::builder()->setStatus( ServiceResponseInterface::SERVICE_INTERNAL_ERROR )
				->setErrors( $response_exception->getData() )
				->build();
		}
		$assistente_dao = new MedicoDAO();
		$dao_response = $assistente_dao->persistMedicoRegistrationVM( $assistente_registration_vm, $passwd,
			function () use ($assistente_registration_vm, $passwd) {
				// return $this->sendEmailConfirmationRegister($assistente_registration_vm, $passwd);
				return true;
			} );

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

		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				// $assistente = (function (Medico $assistente) : Medico { return $assistente; })($dao_response->getData());
				// $service_response->setData(['id_assistente' => $assistente->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;

	}

	private function sendEmailConfirmationRegister(MedicoRegistrationViewModel $assistente_registration_vm, string $passwd): int {

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

	}

	public function assistenteAndMedicoAreLinked(int $id_medico, int $assistente_uid): bool {

		$assistente_dao = new MedicoDAO();
		$dao_response = $assistente_dao->verifyMedicoAndMedicoAreLinked( $id_medico, $assistente_uid );
		return $dao_response->getStatus() === DAOResponseInterface::SUCESS;

	}

	public function updateMedicoData(int $id_medico, array $data): ServiceResponse {

		if (isset( $data ['assinatura'] )) {
			$encoded_string = $data ['assinatura'];
			$target_dir = '../writable/assinatura/';

			$mime_type = finfo_buffer( finfo_open(), $encoded_string, FILEINFO_MIME_TYPE ); // extract mime type
			$extension = $this->mime2ext( $mime_type ); // extract extension from mime type
			$file = uniqid() . '.' . $extension; // rename file as a unique name
			$file_dir = $target_dir . uniqid() . '.' . $extension;
			file_put_contents( $file_dir, $encoded_string );
			header( 'Content-Type: application/json' );
		}

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

		try {
			$assistente_update_vm = MedicoMapper::getMedicoUpdateVMFromArray( $data, $file_dir );
			if (count( $assistente_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 MedicoUpdateViewModel',
				$response_exception->getData() );
			return ServiceResponse::builder()->setStatus( ServiceResponseInterface::SERVICE_INTERNAL_ERROR )
				->setErrors( $response_exception->getData() )
				->build();
		}
		$assistente_dao = new MedicoDAO();
		$image = $assistente_dao->getImageMedico( $id_medico );
		$dao_response = $assistente_dao->persistMedicoUpdateVM( $id_medico, $assistente_update_vm );
		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$this->updateClinicasByMedico( $id_medico, $clinicas );
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				if ($image != null) {
					unlink( $image );
				}
				break;
			case DAOResponseInterface::DUPLICATED_UNIQUE_KEY :
				if (file_exists( $assistente_update_vm->getFoto() ) === true) {
					unlink( $assistente_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( $assistente_update_vm->getFoto() ) === true) {
					unlink( $assistente_update_vm->getFoto() );
				}
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				$service_response->setStatus( ServiceResponseInterface::DATABASE_CONNECTION_ERROR );
				if (file_exists( $assistente_update_vm->getFoto() ) === true) {
					unlink( $assistente_update_vm->getFoto() );
				}
				break;
		}
		return $service_response;

	}

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

		$assistente_dao = new MedicoDAO();
		$dao_response = $assistente_dao->getMedicoList( $id_status, $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();
			$assistente_details_array = MedicoMapper::getMedicoDetailsArrayFromMedicoDetailsVMList( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'medicos' => $assistente_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

	private function updateClinicasByMedico(int $id_medico, array $data) {

		if (count( $data ) > 0) {
			$profissionalService = new ProfissionalService();
			$profissionalService_response = $profissionalService->getIdProfissionalByMedicoId( $id_medico );
			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] ) );
						}
					}
				}
			}
		}

	}

	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();

	}

	// TRABALHANDO COM BASE64
	function mime2ext($mime) {

		$all_mimes = '{"png":["image\/png","image\/x-png"],"bmp":["image\/bmp","image\/x-bmp",
    "image\/x-bitmap","image\/x-xbitmap","image\/x-win-bitmap","image\/x-windows-bmp",
    "image\/ms-bmp","image\/x-ms-bmp","application\/bmp","application\/x-bmp",
    "application\/x-win-bitmap"],"gif":["image\/gif"],"jpeg":["image\/jpeg",
    "image\/pjpeg"],"xspf":["application\/xspf+xml"],"vlc":["application\/videolan"],
    "wmv":["video\/x-ms-wmv","video\/x-ms-asf"],"au":["audio\/x-au"],
    "ac3":["audio\/ac3"],"flac":["audio\/x-flac"],"ogg":["audio\/ogg",
    "video\/ogg","application\/ogg"],"kmz":["application\/vnd.google-earth.kmz"],
    "kml":["application\/vnd.google-earth.kml+xml"],"rtx":["text\/richtext"],
    "rtf":["text\/rtf"],"jar":["application\/java-archive","application\/x-java-application",
    "application\/x-jar"],"zip":["application\/x-zip","application\/zip",
    "application\/x-zip-compressed","application\/s-compressed","multipart\/x-zip"],
    "7zip":["application\/x-compressed"],"xml":["application\/xml","text\/xml"],
    "svg":["image\/svg+xml"],"3g2":["video\/3gpp2"],"3gp":["video\/3gp","video\/3gpp"],
    "mp4":["video\/mp4"],"m4a":["audio\/x-m4a"],"f4v":["video\/x-f4v"],"flv":["video\/x-flv"],
    "webm":["video\/webm"],"aac":["audio\/x-acc"],"m4u":["application\/vnd.mpegurl"],
    "pdf":["application\/pdf","application\/octet-stream"],
    "pptx":["application\/vnd.openxmlformats-officedocument.presentationml.presentation"],
    "ppt":["application\/powerpoint","application\/vnd.ms-powerpoint","application\/vnd.ms-office",
    "application\/msword"],"docx":["application\/vnd.openxmlformats-officedocument.wordprocessingml.document"],
    "xlsx":["application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application\/vnd.ms-excel"],
    "xl":["application\/excel"],"xls":["application\/msexcel","application\/x-msexcel","application\/x-ms-excel",
    "application\/x-excel","application\/x-dos_ms_excel","application\/xls","application\/x-xls"],
    "xsl":["text\/xsl"],"mpeg":["video\/mpeg"],"mov":["video\/quicktime"],"avi":["video\/x-msvideo",
    "video\/msvideo","video\/avi","application\/x-troff-msvideo"],"movie":["video\/x-sgi-movie"],
    "log":["text\/x-log"],"txt":["text\/plain"],"css":["text\/css"],"html":["text\/html"],
    "wav":["audio\/x-wav","audio\/wave","audio\/wav"],"xhtml":["application\/xhtml+xml"],
    "tar":["application\/x-tar"],"tgz":["application\/x-gzip-compressed"],"psd":["application\/x-photoshop",
    "image\/vnd.adobe.photoshop"],"exe":["application\/x-msdownload"],"js":["application\/x-javascript"],
    "mp3":["audio\/mpeg","audio\/mpg","audio\/mpeg3","audio\/mp3"],"rar":["application\/x-rar","application\/rar",
    "application\/x-rar-compressed"],"gzip":["application\/x-gzip"],"hqx":["application\/mac-binhex40",
    "application\/mac-binhex","application\/x-binhex40","application\/x-mac-binhex40"],
    "cpt":["application\/mac-compactpro"],"bin":["application\/macbinary","application\/mac-binary",
    "application\/x-binary","application\/x-macbinary"],"oda":["application\/oda"],
    "ai":["application\/postscript"],"smil":["application\/smil"],"mif":["application\/vnd.mif"],
    "wbxml":["application\/wbxml"],"wmlc":["application\/wmlc"],"dcr":["application\/x-director"],
    "dvi":["application\/x-dvi"],"gtar":["application\/x-gtar"],"php":["application\/x-httpd-php",
    "application\/php","application\/x-php","text\/php","text\/x-php","application\/x-httpd-php-source"],
    "swf":["application\/x-shockwave-flash"],"sit":["application\/x-stuffit"],"z":["application\/x-compress"],
    "mid":["audio\/midi"],"aif":["audio\/x-aiff","audio\/aiff"],"ram":["audio\/x-pn-realaudio"],
    "rpm":["audio\/x-pn-realaudio-plugin"],"ra":["audio\/x-realaudio"],"rv":["video\/vnd.rn-realvideo"],
    "jp2":["image\/jp2","video\/mj2","image\/jpx","image\/jpm"],"tiff":["image\/tiff"],
    "eml":["message\/rfc822"],"pem":["application\/x-x509-user-cert","application\/x-pem-file"],
    "p10":["application\/x-pkcs10","application\/pkcs10"],"p12":["application\/x-pkcs12"],
    "p7a":["application\/x-pkcs7-signature"],"p7c":["application\/pkcs7-mime","application\/x-pkcs7-mime"],"p7r":["application\/x-pkcs7-certreqresp"],"p7s":["application\/pkcs7-signature"],"crt":["application\/x-x509-ca-cert","application\/pkix-cert"],"crl":["application\/pkix-crl","application\/pkcs-crl"],"pgp":["application\/pgp"],"gpg":["application\/gpg-keys"],"rsa":["application\/x-pkcs7"],"ics":["text\/calendar"],"zsh":["text\/x-scriptzsh"],"cdr":["application\/cdr","application\/coreldraw","application\/x-cdr","application\/x-coreldraw","image\/cdr","image\/x-cdr","zz-application\/zz-winassoc-cdr"],"wma":["audio\/x-ms-wma"],"vcf":["text\/x-vcard"],"srt":["text\/srt"],"vtt":["text\/vtt"],"ico":["image\/x-icon","image\/x-ico","image\/vnd.microsoft.icon"],"csv":["text\/x-comma-separated-values","text\/comma-separated-values","application\/vnd.msexcel"],"json":["application\/json","text\/json"]}';
		$all_mimes = json_decode( $all_mimes, true );
		foreach ( $all_mimes as $key => $value ) {
			if (array_search( $mime, $value ) !== false) return $key;
		}
		return false;

	}

}