<?php
namespace Incoviba\Repository\Proyecto\Broker;

use Incoviba\Common;
use Incoviba\Repository;
use Incoviba\Model;

class Data extends Common\Ideal\Repository
{
    public function __construct(Common\Define\Connection $connection,
                                protected Repository\Proyecto\Broker $brokerRepository,
                                protected Repository\Proyecto\Broker\Contact $contactRepository)
    {
        parent::__construct($connection);
    }

    public function getTable(): string
    {
        return 'broker_data';
    }

    public function create(?array $data = null): Model\Proyecto\Broker\Data
    {
        $map = (new Common\Implement\Repository\MapperParser())
            ->register('broker_rut', (new Common\Implement\Repository\Mapper())
                ->setProperty('broker')
                ->setFunction(function($data) {
                    return $this->brokerRepository->fetchById($data['broker_rut']);
                }))
            ->register('representative_id', (new Common\Implement\Repository\Mapper())
                ->setProperty('representative')
                ->setDefault(null)
                ->setFunction(function($data) {
                    if ($data['representative_id'] === null) return null;
                    try {
                        return $this->contactRepository->fetchById($data['representative_id']);
                    } catch (Common\Implement\Exception\EmptyResult) {
                        return null;
                    }
                }))
            ->register('legal_name', (new Common\Implement\Repository\Mapper())
                ->setProperty('legalName')
                ->setDefault(null));
        return $this->parseData(new Model\Proyecto\Broker\Data(), $data, $map);
    }
    public function save(Common\Define\Model $model): Model\Proyecto\Broker\Data
    {
        $model->id = $this->saveNew(
            ['broker_rut', 'representative_id', 'legal_name'],
            [$model->broker->rut, $model->representative?->id, $model->legalName]);
        return $model;
    }

    /**
     * @param Common\Define\Model $model
     * @param array $new_data
     * @return Model\Proyecto\Broker\Data
     * @throws Common\Implement\Exception\EmptyResult
     */
    public function edit(Common\Define\Model $model, array $new_data): Model\Proyecto\Broker\Data
    {
        return $this->update($model, ['representative_id', 'legal_name'], $new_data);
    }

    /**
     * @param int $broker_rut
     * @return Model\Proyecto\Broker\Data
     * @throws Common\Implement\Exception\EmptyResult
     */
    public function fetchByBroker(int $broker_rut): Model\Proyecto\Broker\Data
    {
        $query = $this->connection->getQueryBuilder()
            ->select()
            ->from($this->getTable())
            ->where('broker_rut = :broker_rut');
        return $this->fetchOne($query, ['broker_rut' => $broker_rut]);
    }
}
