<?php
namespace Incoviba\Repository\Contabilidad\Movimiento;

use Incoviba\Common\Define;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement;
use Incoviba\Model;
use Incoviba\Repository;

class Detalle extends Ideal\Repository
{
    public function __construct(Define\Connection $connection,
                                protected Repository\Contabilidad\Movimiento $movimientoRepository,
                                protected Repository\Contabilidad\CentroCosto $centroCostoRepository)
    {
        parent::__construct($connection);
        $this->setTable('movimientos_detalles');
    }

    public function create(?array $data = null): Model\Contabilidad\Movimiento\Detalle
    {
        $map = (new Implement\Repository\MapperParser(['rut', 'digito', 'nombres', 'categoria', 'detalle', 'identificador']))
            ->register('movimiento_id', (new Implement\Repository\Mapper())
                ->setProperty('movimiento')
                ->setFunction(function(array $data) {
                    return $this->movimientoRepository->fetchById($data['movimiento_id']);
                }))
            ->register('centro_costo_id', (new Implement\Repository\Mapper())
                ->setProperty('centroCosto')
                ->setFunction(function(array $data) {
                    return $this->centroCostoRepository->fetchById($data['centro_costo_id']);
                })
                ->setDefault(null));
        return $this->parseData(new Model\Contabilidad\Movimiento\Detalle(), $data, $map);
    }
    public function save(Define\Model $model): Model\Contabilidad\Movimiento\Detalle
    {
        $this->saveNew(
            ['movimiento_id', 'centro_costo_id', 'rut', 'digito', 'nombres', 'categoria', 'detalle', 'identificador'],
            [$model->movimiento->id, $model->centroCosto?->id, $model->rut, $model->digito, $model->nombres, $model->categoria, $model->detalle, $model->identificador]
        );
        return $model;
    }
    public function edit(Define\Model $model, array $new_data): Model\Contabilidad\Movimiento\Detalle
    {
        return $this->update($model, ['movimiento_id', 'centro_costo_id', 'rut', 'digito', 'nombres', 'categoria', 'detalle', 'identificador'], $new_data);
    }
    public function filterData(array $data): array
    {
        $map = [
            'costo_id' => 'centro_costo_id',
            'nombre' => 'nombres',
        ];
        foreach ($map as $source => $dest) {
            if (key_exists($source, $data)) {
                $data[$dest] = $data[$source];
                unset($data[$source]);
            }
        }
        return $data;
    }

    /**
     * @param int $movimiento_id
     * @return Model\Contabilidad\Movimiento\Detalle
     * @throws Implement\Exception\EmptyResult
     */
    public function fetchByMovimiento(int $movimiento_id): Model\Contabilidad\Movimiento\Detalle
    {
        $query = $this->connection->getQueryBuilder()
            ->select()
            ->from($this->getTable())
            ->where('movimiento_id = ?');
        return $this->fetchOne($query, [$movimiento_id]);
    }

    protected function getKey(): string
    {
        return 'movimiento_id';
    }
    protected function setIndex(Define\Model &$model, mixed $value): Ideal\Repository
    {
        if (!isset($model->movimiento)) {
            $model->movimiento = $this->movimientoRepository->fetchById($value);
        }
        return $this;
    }

    protected function getIndex(Define\Model $model): string
    {
        return $model->movimiento->id;
    }
}
