<?php
namespace Incoviba\Controller\API\Contabilidad;

use DateTimeImmutable;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Incoviba\Controller\API\withJson;
use Incoviba\Repository;
use Incoviba\Service;

class Movimientos extends Ideal\Controller
{
    use withJson;

    public function detalles(ServerRequestInterface              $request, ResponseInterface $response,
                             Service\Contabilidad\Movimiento     $movimientoService,
                             Repository\Contabilidad\CentroCosto $centroCostoRepository,
                             int $movimiento_id): ResponseInterface
    {
        $body = $request->getParsedBody();
        $output = [
            'movimiento_id' => $movimiento_id,
            'input' => $body,
            'status' => false,
            'movimiento' => null
        ];
        try {
            $movimiento = $movimientoService->getById($movimiento_id);
            $output['movimiento'] = $this->movimientosToArray([$movimiento])[0];
            $data = [];
            $fieldMap = [
                'centro_costo_id',
                'categoria',
                'detalle',
                'rut',
                'digito',
                'nombres',
                'identificador'
            ];
            foreach ($fieldMap as $field) {
                if (key_exists($field, $body)) {
                    $data[$field] = $body[$field];
                }
            }

            $movimientoService->setDetalles($movimiento, $data);
            $output['movimiento'] = $this->movimientosToArray([$movimientoService->getById($movimiento->id)])[0];
            $output['status'] = true;
        } catch (EmptyResult) {}
        return $this->withJson($response, $output);
    }
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response,
                             Service\Contabilidad\Movimiento $movimientoService): ResponseInterface
    {
        $output = [
            'movimientos' => []
        ];
        try {
            $movimientos = $movimientoService->getAll();
            $output['movimientos'] = $this->movimientosToArray($movimientos);
        } catch (EmptyResult) {}
        return $this->withJson($response, $output);
    }
    public function segment(ServerRequestInterface $request, ResponseInterface $response,
                            Service\Contabilidad\Movimiento $movimientoService): ResponseInterface
    {
        $input = $request->getParsedBody();
        $output = [
            'input' => $input,
            'movimientos' => []
        ];
        try {
            $movimientos = $movimientoService->getAmountStartingFrom($input['from'], $input['amount']);
            $output['movimientos'] = $this->movimientosToArray($movimientos);
        } catch (EmptyResult) {}
        return $this->withJson($response, $output);
    }
    public function sociedad(ServerRequestInterface $request, ResponseInterface $response,
                             Service\Contabilidad\Movimiento $movimientoService): ResponseInterface
    {
        $input = $request->getParsedBody();
        $output = [
            'input' => $input,
            'movimientos' => []
        ];
        $sociedades_ruts = $input['sociedades_ruts'];
        foreach ($sociedades_ruts as $sociedadRut) {
            try {
                    $movimientos = $movimientoService->getAmountBySociedadAndMes($sociedadRut, new DateTimeImmutable($input['mes']), $input['amount'] ?? null);
                    $output['movimientos'] = array_merge($output['movimientos'], $this->movimientosToArray($movimientos));
            } catch (EmptyResult) {}
        }
        return $this->withJson($response, $output);
    }
    public function edit(ServerRequestInterface $request, ResponseInterface $response,
                         Service\Contabilidad\Movimiento $movimientoService): ResponseInterface
    {
        $body = $request->getParsedBody();
        $output = [
            'input' => $body,
            'status' => false,
            'movimiento' => null
        ];
        try {
            $movimiento = $movimientoService->getById($body['id']);
            $output['movimiento'] = $movimientoService->edit($movimiento, $body);
            $output['status'] = true;
        } catch (EmptyResult) {}
        return $this->withJson($response, $output);
    }
    public function remove(ServerRequestInterface $request, ResponseInterface $response,
                           Service\Contabilidad\Movimiento $movimientoService, int $movimiento_id): ResponseInterface
    {
        $output = [
            'movimiento_id' => $movimiento_id,
            'movimiento' => null,
            'status' => false
        ];
        try {
            $movimiento = $movimientoService->getById($movimiento_id);
            $movimientoService->remove($movimiento);
            $output['movimiento'] = $movimiento;
            $output['status'] = true;
        } catch (EmptyResult) {}
        return $this->withJson($response, $output);
    }
    public function findRut(ServerRequestInterface $request, ResponseInterface $response,
                            Service\Contabilidad\Movimiento $movimientoService, int $rut): ResponseInterface
    {
        $output = [
            'rut' => $rut,
            'model' => null,
            'success' => false
        ];
        try {
            $output['model'] = $movimientoService->findRut($rut);
            $output['success'] = true;
        } catch (EmptyResult) {}
        return $this->withJson($response, $output);
    }

    protected function movimientosToArray(array $movimientos): array
    {
        $output = json_decode(json_encode($movimientos), JSON_OBJECT_AS_ARRAY);
        foreach ($output as $i => &$arrayMovimiento) {
            $arrayMovimiento['cuenta'] = json_decode(json_encode($movimientos[$i]->cuenta), JSON_OBJECT_AS_ARRAY);
            $arrayMovimiento['cuenta']['inmobiliaria'] = json_decode(json_encode($movimientos[$i]->cuenta->inmobiliaria), JSON_OBJECT_AS_ARRAY);
            if ($arrayMovimiento['detalles'] !== null) {
                $arrayMovimiento['detalles']['centro_costo'] = $movimientos[$i]->getDetalles()->centroCosto;
            }
        }
        return $output;
    }
}
