<?php

namespace App\Services;

use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\ArquivoDAO;
use App\DAO\Filter\QueryFilter;
use App\DAO\Pagination\Pagination;
use App\Mappers\ArquivoMapper;
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 CodeIgniter\Model;
use Config\Paths;

class ArquivoService extends Service {

	public function registerArquivo(array $data): ServiceResponse {

		if (isset( $_FILES ['arquivo'] )) {
			$ext = "." . pathinfo( $_FILES ['arquivo'] ['name'], PATHINFO_EXTENSION );
			// $ext2 = strtolower(substr($_FILES['arquivo']['name'],-4)); //Pegando extensão do arquivo
			$new_name = date( "Ymd-His" ) . $ext; // Definindo um novo nome para o arquivo
			$ano = date( "Y" );
			$dir = '../writable/arquivo/' . $ano . '/';

			if (!is_dir( $dir )) {
				mkdir( $dir );
			}

			$dir = $dir . $data ['id_paciente'] . '/';
			if (!is_dir( $dir )) {
				mkdir( $dir );
			}

			$dir = $dir . $data ['id_pet'] . '/';
			if (!is_dir( $dir )) {
				mkdir( $dir );
			}

			move_uploaded_file( $_FILES ['arquivo'] ['tmp_name'], $dir . $new_name ); // Fazer upload do arquivo

			$key = "HLuM5EYw5cd0vdJR9yLlM6wt2vte5iniQBqE70nZuhK=";
			$msg = file_get_contents( $dir . $new_name );
			$encrypt = new EncryptService();
			$msg_encrypted = $encrypt->my_encrypt( $msg, $key );
			$file = fopen( $dir . $new_name, "wb" );
			fwrite( $file, $msg_encrypted );
			fclose( $file );
		}

		$galeria_registration_vm = ArquivoMapper::getArquivoRegistrationVMFromArray( $data, $dir . $new_name );
		$galeria_dao = new ArquivoDAO();
		$dao_response = $galeria_dao->persistArquivoRegistrationVM( $galeria_registration_vm );
		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$data = [ 
					'id_arquivo' => $dao_response->getData()
						->getId()
				];
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				$service_response->setData( $data );
				break;
			case DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS :
				unlink( $dir . $new_name );
				break;
			case DAOResponseInterface::DUPLICATED_UNIQUE_KEY :
				unlink( $dir . $new_name );
				$service_response->setStatus( ServiceResponseInterface::VALIDATION_PARAMS_ERROR );
				$service_response->setErrors( $dao_response->getErrors() );
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				unlink( $dir . $new_name );
				$service_response->setStatus( ServiceResponseInterface::DATABASE_CONNECTION_ERROR );
				break;
		}
		return $service_response;

	}

	public function registerArquivoExame(array $data): ServiceResponse {

		if (isset( $_FILES ['arquivo'] )) {
			$ext = "." . pathinfo( $_FILES ['arquivo'] ['name'], PATHINFO_EXTENSION );
			// $ext2 = strtolower(substr($_FILES['arquivo']['name'],-4)); //Pegando extensão do arquivo
			$new_name = date( "Ymd-His" ) . $ext; // Definindo um novo nome para o arquivo
			$ano = date( "Y" );
			$dir = '../writable/arquivo_exames/'. $ano . '/';
			
			if (!is_dir( $dir )) {
				mkdir( $dir );
			}
			
			$dir = $dir . $data ['id_paciente'] . '/';
			if (!is_dir( $dir )) {
				mkdir( $dir );
			}
			
			$dir = $dir . $data ['id_pet'] . '/';
			if (!is_dir( $dir )) {
				mkdir( $dir );
			}

			move_uploaded_file( $_FILES ['arquivo'] ['tmp_name'], $dir . $new_name ); // Fazer upload do arquivo

			$key = "HLuM5EYw5cd0vdJR9yLlM6wt2vte5iniQBqE70nZuhK=";
			$msg = file_get_contents( $dir . $new_name );
			$encrypt = new EncryptService();
			$msg_encrypted = $encrypt->my_encrypt( $msg, $key );
			$file = fopen( $dir . $new_name, "wb" );
			fwrite( $file, $msg_encrypted );
			fclose( $file );
		}

		$galeria_registration_vm = ArquivoMapper::getArquivoRegistrationVMFromArray( $data, $dir . $new_name );
		$galeria_dao = new ArquivoDAO();
		$dao_response = $galeria_dao->persistArquivoExameRegistrationVM( $galeria_registration_vm );
		$service_response = new ServiceResponse();
		switch ($dao_response->getStatus()) {
			case DAOResponseInterface::SUCESS :
				$data = [ 
					'id_arquivo' => $dao_response->getData()
						->getId()
				];
				$service_response->setStatus( ServiceResponseInterface::SUCESS );
				$service_response->setData( $data );
				break;
			case DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS :
				unlink( $dir . $new_name );
				break;
			case DAOResponseInterface::DUPLICATED_UNIQUE_KEY :
				unlink( $dir . $new_name );
				$service_response->setStatus( ServiceResponseInterface::VALIDATION_PARAMS_ERROR );
				$service_response->setErrors( $dao_response->getErrors() );
				break;
			case DAOResponseInterface::DATABASE_CONNECTION_ERROR :
				unlink( $dir . $new_name );
				$service_response->setStatus( ServiceResponseInterface::DATABASE_CONNECTION_ERROR );
				break;
		}
		return $service_response;

	}

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

		$galeria_dao = new ArquivoDAO();
		$dao_response = $galeria_dao->getArquivoList( $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();
			$procedimento_details_array = ArquivoMapper::getArquivoDetailsArrayFromProcedimentoDetailsVMCollection( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'arquivo' => $procedimento_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

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

		$galeria_dao = new ArquivoDAO();
		$dao_response = $galeria_dao->getArquivoListExame( $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();
			$procedimento_details_array = ArquivoMapper::getArquivoDetailsArrayFromProcedimentoDetailsVMCollection( $dao_response_data );
			$pagination = $dao_response->getPagination();
			$data = [ 
				'arquivo' => $procedimento_details_array,
				'pagination' => $pagination ? $pagination->toResponseArray() : null
			];
			$service_response->setData( $data );
		}
		return $service_response;

	}

	public function getArquivo(QueryFilter $query_filter): ServiceResponse {

		$exame_dao = new ArquivoDAO();
		$query_filter_collection = new QueryFilterCollection();
		$query_filter_collection->push( $query_filter );
		$dao_response = $exame_dao->getArquivo( $query_filter_collection );
		$service_response_status = [ 
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND,
			DAOResponseInterface::DATABASE_CONNECTION_ERROR => ServiceResponseInterface::DATABASE_CONNECTION_ERROR
		] [$dao_response->getStatus()];
		$service_response = ServiceResponse::builder()->setStatus( $service_response_status ?? ServiceResponseInterface::UNKNOWN_ERROR)
			->build();
		if ($service_response_status === ServiceResponseInterface::SUCESS) {
			$service_response->setData( $dao_response->getData()
				->toArray() );
		}
		return $service_response;

	}

	public function getArquivoExame(QueryFilter $query_filter): ServiceResponse {

		$exame_dao = new ArquivoDAO();
		$query_filter_collection = new QueryFilterCollection();
		$query_filter_collection->push( $query_filter );
		$dao_response = $exame_dao->getArquivoExame( $query_filter_collection );
		$service_response_status = [ 
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND,
			DAOResponseInterface::DATABASE_CONNECTION_ERROR => ServiceResponseInterface::DATABASE_CONNECTION_ERROR
		] [$dao_response->getStatus()];
		$service_response = ServiceResponse::builder()->setStatus( $service_response_status ?? ServiceResponseInterface::UNKNOWN_ERROR)
			->build();
		if ($service_response_status === ServiceResponseInterface::SUCESS) {
			$service_response->setData( $dao_response->getData()
				->toArray() );
		}
		return $service_response;

	}

	public function deleteArquivo(int $id_galeria): ServiceResponse {

		$galeria_dao = new ArquivoDAO();
		$galeria_data = $galeria_dao->getArquivoId( $id_galeria );

		$dao_response = $galeria_dao->deleteArquivo( $id_galeria );
		$service_response_status = [ 
			DAOResponseInterface::RESTRICT_FK_UPDATE_OR_DELETION => ServiceResponseInterface::RECORD_IS_LINKED,
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND
		] [$dao_response->getStatus()];

		if ($dao_response->getStatus() == 1) {
			unlink( $galeria_data );
		}

		$service_response = ServiceResponse::builder()->setStatus( $service_response_status )
			->build();
		return $service_response;

	}

	public function deleteArquivoExame(int $id_galeria): ServiceResponse {

		$galeria_dao = new ArquivoDAO();
		$galeria_data = $galeria_dao->getArquivoExameId( $id_galeria );

		$dao_response = $galeria_dao->deleteArquivoExame( $id_galeria );
		$service_response_status = [ 
			DAOResponseInterface::RESTRICT_FK_UPDATE_OR_DELETION => ServiceResponseInterface::RECORD_IS_LINKED,
			DAOResponseInterface::SUCESS => ServiceResponseInterface::SUCESS,
			DAOResponseInterface::RECORD_NOT_FOUND => ServiceResponseInterface::RECORD_NOT_FOUND
		] [$dao_response->getStatus()];

		if ($dao_response->getStatus() == 1) {
			unlink( $galeria_data );
		}

		$service_response = ServiceResponse::builder()->setStatus( $service_response_status )
			->build();
		return $service_response;

	}

}