<?php


namespace App\DAO;



use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Pagination\Pagination;
use App\Entities\Raca\Raca;
use App\Mappers\RacaMapper;
use App\Models\RacaModel;
use App\Services\LogService;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\Raca\RacaRegistrationViewModel\RacaRegistrationViewModel;
use App\ViewModels\Raca\RacaUpdateViewModel\RacaUpdateViewModel;
use Exception;

class RacaDAO extends DAO
{
    public function persistRacaRegistrationVM (RacaRegistrationViewModel $raca_registration_vm) : DAOResponse {
        $dao_response = new DAOResponse();
        try {
            $raca = $this->persistRaca($raca_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 = !!$raca->getId()
                    ? DAOResponseInterface::SUCESS
                    : DAOResponseInterface::DATABASE_CONNECTION_ERROR;
            }
        } catch (Exception $exception) {
            log_message('error', json_encode($this->db->error()));
            $status_persistence = DAOResponseInterface::DATABASE_CONNECTION_ERROR;
            $raca = null;
        }
        $this->db->close();
        $dao_response->setStatus($status_persistence);
        if ($status_persistence === DAOResponseInterface::SUCESS) {
            $dao_response->setData($raca);
        }
        return $dao_response;
    }

    private function persistRaca (RacaRegistrationViewModel $raca_registration_vm) : Raca {
        $raca_model = new RacaModel ();
        $raca = RacaMapper::getRacaFromRacaRegistrationVM($raca_registration_vm);
        $raca_model->registerRaca($raca);
        return $raca;
    }

    public function getRacaList (?Pagination $pagination, ?QueryFilterCollection $query_filter_collection, ?QueryOrderCollection $query_order_collection = null) : DAOResponse {
        $sql = '
            SELECT
                raca.id AS id,
                raca.nome AS nome,
                raca.id_especie AS id_especie,
                especie.nome AS especie
            FROM raca
            INNER JOIN especie ON especie.id = raca.id_especie
        ';
        return $this->getDAOResponseFromPaginatedSelect([], $pagination, $query_filter_collection, $query_order_collection, $sql, function (array $result_array) {
            return RacaMapper::getRacaDetailsVMCollectionFromArray($result_array);
        });
    }

    public function deleteRaca (int $id_raca) : DAOResponse {
        $raca_model = new RacaModel ();
        $dao_response = $this->getDAOResponseForDeletion($raca_model, $id_raca);
        return $dao_response;
    }

    public function getRaca (QueryFilterCollection $query_filter_collection) : DAOResponse {
        $sql = '
            SELECT
                raca.id AS id,
                raca.nome AS nome,
                raca.id_especie AS id_especie
            FROM
                raca
        ';
        $binds = [];
        return $this->getDAOResponseFromUniqueRowSelect($binds, $query_filter_collection, $sql, function (array $result_array) {
            return RacaMapper::getRacaDetailsVMFromArray($result_array[0]);
        });
    }

    public function persistRacaUpdateVM (int $id_raca, RacaUpdateViewModel $raca_update_vm) : DAOResponse {
        $status_persistence = $this->persistRacaFromRacaUpdateVM($id_raca, $raca_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_raca", $raca_update_vm->toArray());
        } else {
            $status_response = $status_persistence ? DAOResponseInterface::SUCESS :  DAOResponseInterface::RECORD_NOT_FOUND;
        }
        $dao_response->setStatus($status_response);
        return $dao_response;
    }

    private function persistRacaFromRacaUpdateVM (int $id_raca, RacaUpdateViewModel $raca_update_vm) : bool {
        $raca_model = new RacaModel();
        $raca = RacaMapper::getRacaFromRacaUpdateVM($raca_update_vm);
        $sucess_update = $raca_model->updateRacaByID($id_raca, $raca);
        return $sucess_update;
    }

}
