<?php
namespace Incoviba\Service\Venta;

use DateTimeImmutable;
use DateMalformedStringException;
use PDOException;
use Psr\Log\LoggerInterface;
use Incoviba\Common\Define;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement;
use Incoviba\Exception\ServiceAction;
use Incoviba\Model;
use Incoviba\Repository;

class Reservation extends Ideal\Service\API
{
    public function __construct(LoggerInterface $logger, protected Repository\Venta\Reservation $reservationRepository)
    {
        parent::__construct($logger);
    }

    public function getAll(null|string|array $order = null): array
    {
        try {
            return $this->reservationRepository->fetchAll($order);
        } catch (Implement\Exception\EmptyResult) {
            return [];
        }
    }

    public function get(int $id): Model\Venta\Reservation
    {
        try {
            return $this->process($this->reservationRepository->fetchById($id));
        } catch (Implement\Exception\EmptyResult $exception) {
            throw new ServiceAction\Read(__CLASS__, $exception);
        }
    }

    public function add(array $data): Model\Venta\Reservation
    {
        try {
            $date = new DateTimeImmutable();
            try {
                $date = new DateTimeImmutable($data['date']);
            } catch (DateMalformedStringException) {}
            return $this->process($this->reservationRepository->fetchByBuyerAndDate($data['buyer_rut'], $date));
        } catch (Implement\Exception\EmptyResult) {}

        try {
            $reservationData = $this->reservationRepository->filterData($data);
            $reservation = $this->reservationRepository->create($reservationData);
            $this->reservationRepository->save($reservation);
            return $this->process($reservation);
        } catch (PDOException $exception) {
            throw new ServiceAction\Create(__CLASS__, $exception);
        }
    }
    public function edit(Define\Model $model, array $new_data): Model\Venta\Reservation
    {
        try {
            return $this->process($this->reservationRepository->edit($model, $new_data));
        } catch (PDOException | Implement\Exception\EmptyResult $exception) {
            throw new ServiceAction\Update(__CLASS__, $exception);
        }
    }
    public function delete(int $id): Model\Venta\Reservation
    {
        try {
            $reservation = $this->reservationRepository->fetchById($id);
            $this->reservationRepository->remove($reservation);
            return $reservation;
        } catch (PDOException | Implement\Exception\EmptyResult $exception) {
            throw new ServiceAction\Delete(__CLASS__, $exception);
        }
    }
    protected function process(Define\Model $model): Model\Venta\Reservation
    {
        return $model;
    }
}
