<?php

namespace App\DAO;

use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Pagination\Pagination;
use App\Entities\PreAgendamento\PreAgendamento;
use App\Mappers\PreAgendamentoMapper;
use App\Models\PreAgendamentoModel;
use App\Services\LogService;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\PreAgendamento\PreAgendamentoRegistrationViewModel\PreAgendamentoRegistrationViewModel;
use App\ViewModels\PreAgendamento\PreAgendamentoUpdateViewModel\PreAgendamentoUpdateViewModel;
use Exception;

class PreAgendamentoDAO extends DAO {

	public function persistPreAgendamentoRegistrationVM(PreAgendamentoRegistrationViewModel $preagendamento_registration_vm): DAOResponse {

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

	}

	private function persistPreAgendamento(PreAgendamentoRegistrationViewModel $preagendamento_registration_vm): PreAgendamento {

		$preagendamento_model = new PreAgendamentoModel();
		$preagendamento = PreAgendamentoMapper::getPreAgendamentoFromPreAgendamentoRegistrationVM( $preagendamento_registration_vm );
		$preagendamento_model->registerPreAgendamento( $preagendamento );
		return $preagendamento;

	}

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

		$sql = <<<SQL
		     SELECT 
		         preagendamento_especialidade.id as pre_agendamento_id,
		         preagendamento_especialidade.id_agenda_especialidade as id_agenda_especialidade,
		         preagendamento_especialidade.cliente_nome as cliente_nome,
		         preagendamento_especialidade.cliente_telefone as cliente_telefone,
		         preagendamento_especialidade.id_especialidade as id_especialidade,
		         preagendamento_especialidade.status AS status_id,
		         preagendamento_especialidade_status.descricao as status_descricao,
		         especialidade.descricao as descricao_especialidade,
		         SUBSTRING(agenda_especialidade.hora_inicio, 1, 5) AS agenda_hora_inicio,
		         SUBSTRING(agenda_especialidade.hora_final, 1, 5) AS agenda_hora_final,
		         agenda_especialidade.data AS agenda_data
		     FROM 
		     	preagendamento_especialidade, especialidade, agenda_especialidade, preagendamento_especialidade_status
		     WHERE 
		     	preagendamento_especialidade.id_especialidade = especialidade.id AND 
		     	agenda_especialidade.id = preagendamento_especialidade.id_agenda_especialidade AND 
		     	preagendamento_especialidade_status.id = preagendamento_especialidade.status AND 
		     	preagendamento_especialidade.status in (1,2)
		SQL;
		return $this->getDAOResponseFromPaginatedSelect( [ ], $pagination, $query_filter_collection, $query_order_collection, $sql,
			function (array $result_array) {
				return PreAgendamentoMapper::getPreAgendamentoDetailsVMCollectionFromArray( $result_array );
			} );

	}

	public function deletePreAgendamento(int $id_procedimento): DAOResponse {

		$preagendamento_model = new PreAgendamentoModel();
		$dao_response = $this->getDAOResponseForDeletion( $preagendamento_model, $id_procedimento );
		return $dao_response;

	}

	public function getPreAgendamento(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = '
            SELECT
                EXAME.id AS id,
                EXAME.nome AS nome
            FROM
                EXAME
        ';
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
			function (array $result_array) {
				return PreAgendamentoMapper::getPreAgendamentoDetailsVMFromArray( $result_array [0] );
			} );

	}

	public function persistPreAgendamentoUpdateVM(int $id_procedimento, PreAgendamentoUpdateViewModel $preagendamento_update_vm): DAOResponse {

		$status_persistence = $this->persistPreAgendamentoFromPreAgendamentoUpdateVM( $id_procedimento, $preagendamento_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",
				$preagendamento_update_vm->toArray() );
		} else {
			$status_response = $status_persistence ? DAOResponseInterface::SUCESS : DAOResponseInterface::RECORD_NOT_FOUND;
		}
		$dao_response->setStatus( $status_response );
		return $dao_response;

	}

	private function persistPreAgendamentoFromPreAgendamentoUpdateVM(int $id_procedimento, PreAgendamentoUpdateViewModel $preagendamento_update_vm): bool {

		$preagendamento_model = new PreAgendamentoModel();
		$preagendamento = PreAgendamentoMapper::getPreAgendamentoFromPreAgendamentoUpdateVM( $preagendamento_update_vm );
		$sucess_update = $preagendamento_model->updatePreAgendamentoByID( $id_procedimento, $preagendamento );
		return $sucess_update;

	}

}
