<?php

namespace App\DAO;

use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Pagination\Pagination;
use App\Entities\Arquivo\Arquivo;
use App\Mappers\AgendaMapper;
use App\Mappers\ArquivoMapper;
use App\Models\ArquivoExameModel;
use App\Models\ArquivoModel;
use App\Services\EncryptService;
use App\Services\JWTService;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\Arquivo\ArquivoRegistrationViewModel\ArquivoRegistrationViewModel;
use CodeIgniter\Model;
use Exception;

class ArquivoDAO extends DAO {

	public function persistArquivoRegistrationVM(ArquivoRegistrationViewModel $arquivo_registration_vm): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$galeria = $this->persistArquivo( $arquivo_registration_vm );
			$error = $this->db->error();
			if ($error && $error ['code']) {
				$status_persistence = $error ['code'];
				$dao_response_errors = [ ];
				if (strpos( $error ['message'], 'procedimento.descricao' ) !== false) {
					$dao_response_errors ['descricao'] = 'Esse procedimento já existe';
				}
				if (strpos( $error ['message'], 'fk_procedimento_id_tipo_procedimento' ) !== false) {
					$dao_response_errors ['id_tipo_procedimento'] = 'O tipo de procedimento não existe';
				}
				if (strpos( $error ['message'], 'fk_procedimento_criado_por' ) !== false) {
					$dao_response_errors ['criado_por'] = 'Esse usuário não existe.';
				}
				$dao_response->setErrors( $dao_response_errors );
				log_message( 'error', json_encode( $error ) );
			} else {
				$status_persistence = !!$galeria->getId() ? DAOResponseInterface::SUCESS : DAOResponseInterface::DATABASE_CONNECTION_ERROR;
			}
		} catch ( Exception $exception ) {
			log_message( 'error', json_encode( $this->db->error() ) );
			$status_persistence = DAOResponseInterface::DATABASE_CONNECTION_ERROR;
			$galeria = null;
		}
		$this->db->close();
		$dao_response->setStatus( $status_persistence );
		if ($status_persistence === DAOResponseInterface::SUCESS) {
			$dao_response->setData( $galeria );
		}
		return $dao_response;

	}

	public function persistArquivoExameRegistrationVM(ArquivoRegistrationViewModel $arquivo_registration_vm): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$galeria = $this->persistArquivoExame( $arquivo_registration_vm );
			$error = $this->db->error();
			if ($error && $error ['code']) {
				$status_persistence = $error ['code'];
				$dao_response_errors = [ ];
				if (strpos( $error ['message'], 'procedimento.descricao' ) !== false) {
					$dao_response_errors ['descricao'] = 'Esse procedimento já existe';
				}
				if (strpos( $error ['message'], 'fk_procedimento_id_tipo_procedimento' ) !== false) {
					$dao_response_errors ['id_tipo_procedimento'] = 'O tipo de procedimento não existe';
				}
				if (strpos( $error ['message'], 'fk_procedimento_criado_por' ) !== false) {
					$dao_response_errors ['criado_por'] = 'Esse usuário não existe.';
				}
				$dao_response->setErrors( $dao_response_errors );
				log_message( 'error', json_encode( $error ) );
			} else {
				$status_persistence = !!$galeria->getId() ? DAOResponseInterface::SUCESS : DAOResponseInterface::DATABASE_CONNECTION_ERROR;
			}
		} catch ( Exception $exception ) {
			log_message( 'error', json_encode( $this->db->error() ) );
			$status_persistence = DAOResponseInterface::DATABASE_CONNECTION_ERROR;
			$galeria = null;
		}
		$this->db->close();
		$dao_response->setStatus( $status_persistence );
		if ($status_persistence === DAOResponseInterface::SUCESS) {
			$dao_response->setData( $galeria );
		}
		return $dao_response;

	}

	private function persistArquivo(ArquivoRegistrationViewModel $arquivo_registration_vm): Arquivo {

		$arquivo_model = new ArquivoModel();
		$galeria = ArquivoMapper::getArquivoFromArquivoRegistrationVM( $arquivo_registration_vm );
		$arquivo_model->registerArquivo( $galeria );
		return $galeria;

	}

	private function persistArquivoExame(ArquivoRegistrationViewModel $arquivo_registration_vm): Arquivo {

		$arquivo_model = new ArquivoExameModel();
		$galeria = ArquivoMapper::getArquivoFromArquivoRegistrationVM( $arquivo_registration_vm );
		$arquivo_model->registerArquivo( $galeria );
		return $galeria;

	}

	# ----------------------------------------------------------------------------------------------------------------#
	public function getArquivoList(?Pagination $pagination, ?QueryFilterCollection $query_filter_collection,
			?QueryOrderCollection $query_order_collection = null): DAOResponse {

		$jwt_payload = JWTService::getTokenJWTPayload();
		if ($jwt_payload->getProfile() === PERFIL_PACIENTE) {
			$sql = '
            SELECT
                arquivo.id as id,
                arquivo.id_clinica as id_clinica,
                arquivo.id_medico as id_medico,
                arquivo.id_paciente as id_paciente,
                arquivo.arquivo as arquivo,
				arquivo.id_pet as id_pet,
                arquivo.descricao as descricao,
                arquivo.tutor_view as tutor_view,
                arquivo.criado_em as criado_em
            FROM
                arquivo
            WHERE
                arquivo.tutor_view = 1
        ';
		} else {
			$sql = '
            SELECT
                arquivo.id as id,
                arquivo.id_clinica as id_clinica,
                arquivo.id_medico as id_medico,
                arquivo.id_paciente as id_paciente,
                arquivo.arquivo as arquivo,
				arquivo.id_pet as id_pet,
                arquivo.descricao as descricao,
                arquivo.tutor_view as tutor_view,
                arquivo.criado_em as criado_em
            FROM
                arquivo
        ';
		}
		return $this->getDAOResponseFromPaginatedSelect( [ ], $pagination, $query_filter_collection, $query_order_collection, $sql,
				function (array $result_array) {
					return ArquivoMapper::getArquivoListVMCollectionFromArray( $result_array );
				} );

	}

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

		$jwt_payload = JWTService::getTokenJWTPayload();
		if ($jwt_payload->getProfile() === PERFIL_PACIENTE) {
			$sql = '
            SELECT
                arquivo_exame.id as id,
                arquivo_exame.id_clinica as id_clinica,
                arquivo_exame.id_medico as id_medico,
                arquivo_exame.id_paciente as id_paciente,
                arquivo_exame.arquivo as arquivo,
				arquivo_exame.id_pet as id_pet,
                arquivo_exame.descricao as descricao,
                arquivo_exame.tutor_view as tutor_view,
                arquivo_exame.criado_em as criado_em
            FROM
                arquivo_exame
            WHERE
                arquivo_exame.tutor_view = 1
        ';
		} else {
			$sql = '
            SELECT
                arquivo_exame.id as id,
                arquivo_exame.id_clinica as id_clinica,
                arquivo_exame.id_medico as id_medico,
                arquivo_exame.id_paciente as id_paciente,
                arquivo_exame.arquivo as arquivo,
				arquivo_exame.id_pet as id_pet,
                arquivo_exame.descricao as descricao,
                arquivo_exame.tutor_view as tutor_view,
                arquivo_exame.criado_em as criado_em
            FROM
                arquivo_exame
        ';
		}
		return $this->getDAOResponseFromPaginatedSelect( [ ], $pagination, $query_filter_collection, $query_order_collection, $sql,
				function (array $result_array) {
					return ArquivoMapper::getArquivoListVMCollectionFromArray( $result_array );
				} );

	}

	# --------------------------------------------------------------------------------------------------------------------#
	public function getArquivo(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = '
            SELECT
                arquivo.id as id,
                arquivo.id_clinica as id_clinica,
                arquivo.id_medico as id_medico,
                arquivo.id_paciente as id_paciente,
                arquivo.arquivo as arquivo,
                arquivo.descricao as descricao,
                arquivo.tutor_view as tutor_view
            FROM
                arquivo
        ';
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
				function (array $result_array) {
					$key = "HLuM5EYw5cd0vdJR9yLlM6wt2vte5iniQBqE70nZuhK=";
					$get_file = file_get_contents( $result_array [0] ["arquivo"] );
					$encrypt = new EncryptService();

					$msg_decrypted = $encrypt->my_decrypt( $get_file, $key );
					$base64 = base64_encode( $msg_decrypted );

					return ArquivoMapper::getArquivoDetailsVMFromArray( $result_array [0], $base64 );
				} );

	}

	public function getArquivoExame(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = '
            SELECT
                arquivo_exame.id as id,
                arquivo_exame.id_clinica as id_clinica,
                arquivo_exame.id_medico as id_medico,
                arquivo_exame.id_paciente as id_paciente,
                arquivo_exame.arquivo as arquivo,
                arquivo_exame.descricao as descricao,
                arquivo_exame.tutor_view as tutor_view
            FROM
                arquivo_exame
        ';
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
				function (array $result_array) {
					$key = "HLuM5EYw5cd0vdJR9yLlM6wt2vte5iniQBqE70nZuhK=";
					$get_file = file_get_contents( $result_array [0] ["arquivo"] );
					$encrypt = new EncryptService();

					$msg_decrypted = $encrypt->my_decrypt( $get_file, $key );
					$base64 = base64_encode( $msg_decrypted );

					return ArquivoMapper::getArquivoDetailsVMFromArray( $result_array [0], $base64 );
				} );

	}

	# -------------------------------------------------------------------------------------------------------------------------#
	public function getArquivoId(int $id_arquivo) {

		$sql = '
            SELECT
                arquivo.id as id,
                arquivo.id_clinica as id_clinica,
                arquivo.id_medico as id_medico,
                arquivo.id_paciente as id_paciente,
                arquivo.arquivo as arquivo,
                arquivo.descricao as descricao
            FROM
                arquivo
            WHERE
                arquivo.id = :id_arquivo:
        ';
		$binds = [ 
				'id_arquivo' => $id_arquivo
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return ($result_array [0] ['arquivo']);

	}

	public function getArquivoExameId(int $id_arquivo) {

		$sql = '
            SELECT
                arquivo_exame.id as id,
                arquivo_exame.id_clinica as id_clinica,
                arquivo_exame.id_medico as id_medico,
                arquivo_exame.id_paciente as id_paciente,
                arquivo_exame.arquivo as arquivo,
                arquivo_exame.descricao as descricao
            FROM
                arquivo_exame
            WHERE
                arquivo_exame.id = :id_arquivo:
        ';
		$binds = [ 
				'id_arquivo' => $id_arquivo
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();
		return ($result_array [0] ['arquivo']);

	}

	public function deleteArquivo(int $id_galeria): DAOResponse {

		$arquivo_model = new ArquivoModel();
		$dao_response = $this->getDAOResponseForDeletion( $arquivo_model, $id_galeria );
		return $dao_response;

	}

	public function deleteArquivoExame(int $id_galeria): DAOResponse {

		$arquivo_model = new ArquivoExameModel();
		$dao_response = $this->getDAOResponseForDeletion( $arquivo_model, $id_galeria );
		return $dao_response;

	}

}