<?php
namespace Incoviba\Service\Venta;

use PDOException;
use Incoviba\Common\Implement\Repository\Factory;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Incoviba\Exception\ServiceAction\Read;
use Incoviba\Repository;
use Incoviba\Model;

class Unidad
{
    public function __construct(
        protected Repository\Venta\Unidad $unidadRepository,
        protected Repository\Venta\Unidad\Prorrateo $unidadProrrateoRepository,
        protected Precio    $precioService
    ) {}

    /**
     * @param int $unidad_id
     * @return Model\Venta\Unidad
     * @throws Read
     */
    public function getById(int $unidad_id): Model\Venta\Unidad
    {
        try {
            return $this->process($this->unidadRepository->fetchById($unidad_id));
        } catch (EmptyResult $exception) {
            throw new Read(__CLASS__, $exception);
        }
    }
    public function getByVenta(int $venta_id): array
    {
        return array_map([$this, 'process'], $this->unidadRepository->fetchByVenta($venta_id));
    }
    public function getByPropiedad(int $propiedad_id): array
    {
        return array_map([$this, 'process'], $this->unidadRepository->fetchByPropiedad($propiedad_id));
    }
    public function getByCierre(int $cierre_id): array
    {
        return array_map([$this, 'process'], $this->unidadRepository->fetchByCierre($cierre_id));
    }
    public function getByProyecto(int $proyecto_id): array
    {
        return array_map([$this, 'process'], $this->unidadRepository->fetchByProyecto($proyecto_id));
    }
    public function getDisponiblesByProyecto(int $proyecto_id): array
    {
        return $this->unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
    }
    public function getByIdForSearch(int $unidad_id): array
    {
        return $this->unidadRepository->fetchByIdForSearch($unidad_id);
    }

    public function editProrrateo(int $unidad_id, array $new_data): Model\Venta\Unidad
    {
        $model = $this->unidadRepository->fetchById($unidad_id);
        $filteredData = $this->unidadProrrateoRepository->filterData($new_data);
        try {
            $prorrateo = $this->unidadProrrateoRepository->fetchByUnidad($model->id);
            $prorrateo = $this->unidadProrrateoRepository->edit($prorrateo, $filteredData);
        } catch (PDOException | EmptyResult) {
            $filteredData['unidad_id'] = $model->id;
            $prorrateo = $this->unidadProrrateoRepository->create($filteredData);
            $this->unidadProrrateoRepository->save($prorrateo);
        }
        $model->prorrateo = $prorrateo->prorrateo;
        return $model;
    }

    protected function process($unidad): Model\Venta\Unidad
    {
        try {
            $unidad->precios = $this->precioService->getByUnidad($unidad->id);
            $unidad->currentPrecio = $this->precioService->getVigenteByUnidad($unidad->id);
        } catch (Read) {}
        $unidad->addFactory('sold', (new Factory())
            ->setCallable([$this->unidadRepository, 'fetchSoldByUnidad'])
            ->setArgs(['unidad_id' => $unidad->id])
        );
        return $unidad;
    }
}
