<?php


namespace App\DAO;



use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Pagination\Pagination;
use App\Entities\Especie\Especie;
use App\Mappers\EspecieMapper;
use App\Models\EspecieModel;
use App\Services\LogService;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\Especie\EspecieRegistrationViewModel\EspecieRegistrationViewModel;
use App\ViewModels\Especie\EspecieUpdateViewModel\EspecieUpdateViewModel;
use Exception;

class EspecieDAO extends DAO
{
    public function persistEspecieRegistrationVM (EspecieRegistrationViewModel $especie_registration_vm) : DAOResponse {
        $dao_response = new DAOResponse();
        try {
            $especie = $this->persistEspecie($especie_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 = !!$especie->getId()
                    ? DAOResponseInterface::SUCESS
                    : DAOResponseInterface::DATABASE_CONNECTION_ERROR;
            }
        } catch (Exception $exception) {
            log_message('error', json_encode($this->db->error()));
            $status_persistence = DAOResponseInterface::DATABASE_CONNECTION_ERROR;
            $especie = null;
        }
        $this->db->close();
        $dao_response->setStatus($status_persistence);
        if ($status_persistence === DAOResponseInterface::SUCESS) {
            $dao_response->setData($especie);
        }
        return $dao_response;
    }

    private function persistEspecie (EspecieRegistrationViewModel $especie_registration_vm) : Especie {
        $especie_model = new EspecieModel ();
        $especie = EspecieMapper::getEspecieFromEspecieRegistrationVM($especie_registration_vm);
        $especie_model->registerEspecie($especie);
        return $especie;
    }

    public function getEspecieList (?Pagination $pagination, ?QueryFilterCollection $query_filter_collection, ?QueryOrderCollection $query_order_collection = null) : DAOResponse {
        $sql = '
            SELECT
                especie.id AS id,
                especie.nome AS nome
            FROM
                especie
        ';
        return $this->getDAOResponseFromPaginatedSelect([], $pagination, $query_filter_collection, $query_order_collection, $sql, function (array $result_array) {
            return EspecieMapper::getEspecieDetailsVMCollectionFromArray($result_array);
        });
    }

    public function deleteEspecie (int $id_procedimento) : DAOResponse {
        $especie_model = new EspecieModel ();
        $dao_response = $this->getDAOResponseForDeletion($especie_model, $id_procedimento);
        return $dao_response;
    }

    public function getEspecie (QueryFilterCollection $query_filter_collection) : DAOResponse {
        $sql = '
            SELECT
                especie.id AS id,
                especie.nome AS nome
            FROM
                especie
        ';
        $binds = [];
        return $this->getDAOResponseFromUniqueRowSelect($binds, $query_filter_collection, $sql, function (array $result_array) {
            return EspecieMapper::getEspecieDetailsVMFromArray($result_array[0]);
        });
    }

    public function persistEspecieUpdateVM (int $id_procedimento, EspecieUpdateViewModel $especie_update_vm) : DAOResponse {
        $status_persistence = $this->persistEspecieFromEspecieUpdateVM($id_procedimento, $especie_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", $especie_update_vm->toArray());
        } else {
            $status_response = $status_persistence ? DAOResponseInterface::SUCESS :  DAOResponseInterface::RECORD_NOT_FOUND;
        }
        $dao_response->setStatus($status_response);
        return $dao_response;
    }

    private function persistEspecieFromEspecieUpdateVM (int $id_procedimento, EspecieUpdateViewModel $especie_update_vm) : bool {
        $especie_model = new EspecieModel();
        $especie = EspecieMapper::getEspecieFromEspecieUpdateVM($especie_update_vm);
        $sucess_update = $especie_model->updateEspecieByID($id_procedimento, $especie);
        return $sucess_update;
    }

}