<?php

namespace App\DAO;

use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Pagination\Pagination;
use App\Entities\EspecialidadeProcedimento\EspecialidadeProcedimento;
use App\Mappers\EspecialidadeProcedimentoMapper;
use App\Models\EspecialidadeProcedimentoModel;
use App\Services\LogService;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\EspecialidadeProcedimento\EspecialidadeProcedimentoRegistrationViewModel\EspecialidadeProcedimentoRegistrationViewModel;
use App\ViewModels\EspecialidadeProcedimento\EspecialidadeProcedimentoUpdateViewModel\EspecialidadeProcedimentoUpdateViewModel;
use Exception;

class EspecialidadeProcedimentoDAO extends DAO {

	public function persistEspecialidadeProcedimentoRegistrationVM(EspecialidadeProcedimentoRegistrationViewModel $exame_registration_vm): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$exame = $this->persistEspecialidadeProcedimento( $exame_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';
				// }
				$dao_response->setErrors( $dao_response_errors );
				log_message( 'error', json_encode( $error ) );
			} else {
				$status_persistence = !!$exame->getId() ? DAOResponseInterface::SUCESS : DAOResponseInterface::DATABASE_CONNECTION_ERROR;
			}
		} catch ( Exception $exception ) {
			log_message( 'error', json_encode( $this->db->error() ) );
			$status_persistence = DAOResponseInterface::DATABASE_CONNECTION_ERROR;
			$exame = null;
		}
		$this->db->close();
		$dao_response->setStatus( $status_persistence );
		if ($status_persistence === DAOResponseInterface::SUCESS) {
			$dao_response->setData( $exame );
		}
		return $dao_response;

	}

	private function persistEspecialidadeProcedimento(EspecialidadeProcedimentoRegistrationViewModel $exame_registration_vm): EspecialidadeProcedimento {

		$exame_model = new EspecialidadeProcedimentoModel();
		$exame = EspecialidadeProcedimentoMapper::getEspecialidadeProcedimentoFromEspecialidadeProcedimentoRegistrationVM( $exame_registration_vm );
		$exame_model->registerEspecialidadeProcedimento( $exame );
		return $exame;

	}

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

		$sql = '
        SELECT 
        especialidade_procedimento.id as id,
        id_especialidade, 
        id_procedimento, 
        tipo_procedimento.id as id_tipo_procedimento,
        procedimento.descricao as descricao_procedimento,
        especialidade.descricao as descricao_especialidade
        FROM especialidade_procedimento 
        INNER JOIN especialidade on especialidade_procedimento.id_especialidade = especialidade.id 
        INNER JOIN procedimento  on especialidade_procedimento.id_procedimento  = procedimento.id
        INNER JOIN tipo_procedimento on tipo_procedimento.id = procedimento.id_tipo_procedimento  
        ';
		return $this->getDAOResponseFromPaginatedSelect( [ ], $pagination, $query_filter_collection, $query_order_collection, $sql,
			function (array $result_array) {
				return EspecialidadeProcedimentoMapper::getEspecialidadeProcedimentoDetailsVMCollectionFromArray( $result_array );
			} );

	}

	public function deleteEspecialidadeProcedimento(int $id_procedimento): DAOResponse {

		$exame_model = new EspecialidadeProcedimentoModel();
		$dao_response = $this->getDAOResponseForDeletion( $exame_model, $id_procedimento );
		return $dao_response;

	}

	public function getEspecialidadeProcedimento(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = '
        SELECT 
        especialidade_procedimento.id as id,
        id_especialidade, 
        id_procedimento, 
        tipo_procedimento.id as id_tipo_procedimento,
        procedimento.descricao as descricao_procedimento,
        especialidade.descricao as descricao_especialidade
        FROM especialidade_procedimento 
        INNER JOIN especialidade on especialidade_procedimento.id_especialidade = especialidade.id 
        INNER JOIN procedimento  on especialidade_procedimento.id_procedimento  = procedimento.id
        INNER JOIN tipo_procedimento on tipo_procedimento.id = procedimento.id_tipo_procedimento  
        ';
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
			function (array $result_array) {
				return EspecialidadeProcedimentoMapper::getEspecialidadeProcedimentoDetailsVMFromArray( $result_array [0] );
			} );

	}

	public function persistEspecialidadeProcedimentoUpdateVM(int $id_procedimento, EspecialidadeProcedimentoUpdateViewModel $exame_update_vm): DAOResponse {

		$status_persistence = $this->persistEspecialidadeProcedimentoFromEspecialidadeProcedimentoUpdateVM( $id_procedimento, $exame_update_vm );
		$error = $this->db->error();
		$this->db->close();
		$dao_response = new DAOResponse();
		if ($error && $error ['code']) {
			$status_response = $error ['code'];
			$dao_response_errors = [ ];
			$dao_response->setErrors( $dao_response_errors );
			(new LogService())->log_error( $status_response, "Ocorreu um erro durante a atualização do procedimento $id_procedimento",
				$exame_update_vm->toArray() );
		} else {
			$status_response = $status_persistence ? DAOResponseInterface::SUCESS : DAOResponseInterface::RECORD_NOT_FOUND;
		}
		$dao_response->setStatus( $status_response );
		return $dao_response;

	}

	private function persistEspecialidadeProcedimentoFromEspecialidadeProcedimentoUpdateVM(int $id_procedimento,
			EspecialidadeProcedimentoUpdateViewModel $exame_update_vm): bool {

		$exame_model = new EspecialidadeProcedimentoModel();
		$exame = EspecialidadeProcedimentoMapper::getEspecialidadeProcedimentoFromEspecialidadeProcedimentoUpdateVM( $exame_update_vm );
		$sucess_update = $exame_model->updateEspecialidadeProcedimentoByID( $id_procedimento, $exame );
		return $sucess_update;

	}

	public function getPorcedimentosByEspecialidadeByUnidade(int $idUnidade, int $idEspecialidade): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			select 
				distinct ep.id_procedimento , p.descricao as procedimento
			from 
				especialidade_procedimento ep, especialidade e , procedimento p
			where 
				ep.id_unidade = :unidade_id: 
				and ep.id_especialidade = :especialidade_id: 
				and ep.id_especialidade = e.id
				and ep.id_procedimento = p.id
		SQL;

		$binds = [ 
			'unidade_id' => $idUnidade,
			'especialidade_id' => $idEspecialidade
		];

		$conn = db_connect();
		$resp = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
			return $dao_response;
		}

		$dao_response->setData( [ 
			'procedimentos' => $resp
		] );
		$dao_response->setStatus( DAOResponseInterface::SUCESS );

		return $dao_response;

	}

}