<?php
namespace Incoviba\Controller;

use Incoviba\Common\Alias\View;
use Incoviba\Common\Implement\Exception\EmptyRedis;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Incoviba\Model;
use Incoviba\Repository;
use Incoviba\Service;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class Ventas
{
    use withRedis;

    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, View $view,
                             Service\Redis $redisService, Service\Proyecto $proyectoService,
                             Repository\Proyecto $proyectoRepository): ResponseInterface
    {
        $redisKey = "proyectos:vendibles";
        try {
            $proyectos = $this->fetchRedis($redisService, $redisKey);
        } catch (EmptyRedis) {
            $proyectos = array_map(function(Model\Proyecto $proyecto) {
                return ['id' => $proyecto->id, 'descripcion' => $proyecto->descripcion];
            }, $proyectoService->getVendibles());
            $this->saveRedis($redisService, $redisKey, $proyectos);
        }
        return $view->render($response, 'ventas.list', compact('proyectos'));
    }
    public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
                         Service\Venta $service, int $venta_id): ResponseInterface
    {
        try {
            $venta = $service->getById($venta_id);
            return $view->render($response, 'ventas.show', compact('venta'));
        } catch (EmptyResult) {
            $response = $response->withStatus(404);
            return $view->render($response, 'not_found');
        }
    }
    public function showUnidad(ServerRequestInterface $request, ResponseInterface $response, View $view,
                               Service\Venta $service, string $proyecto_nombre, int $unidad_descripcion): ResponseInterface
    {
        $proyecto_nombre = urldecode($proyecto_nombre);
        $venta = $service->getByProyectoAndUnidad($proyecto_nombre, $unidad_descripcion);
        return $view->render($response, 'ventas.show', compact('venta'));
    }
    public function edit(ServerRequestInterface $request, ResponseInterface $response, View $view,
                         Service\Venta $service, int $venta_id): ResponseInterface
    {
        $venta = $service->getById($venta_id);
        return $view->render($response, 'ventas.edit', compact('venta'));
    }
    public function propietario(ServerRequestInterface $request, ResponseInterface $response, View $view,
                                Service\Venta $service, Repository\Region $regionRepository, int $venta_id): ResponseInterface
    {
        $venta = $service->getById($venta_id);
        $propietario = $venta->propietario();
        $regiones = $regionRepository->fetchAll();
        usort($regiones, function(Model\Region $a, Model\Region $b) {
            return $a->numeracion - $b->numeracion;
        });
        return $view->render($response, 'ventas.propietarios.edit', compact('propietario',
            'venta_id', 'regiones'));
    }
    public function propiedad(ServerRequestInterface $request, ResponseInterface $response, View $view,
                              Service\Venta $service, Service\Venta\Unidad $unidadService, int $venta_id): ResponseInterface
    {
        $venta = $service->getById($venta_id);
        $propiedad = $venta->propiedad();
        $proyecto = $venta->proyecto();
        $unidades = $unidadService->getDisponiblesByProyecto($proyecto->id);
        $tiposUnidades = [];
        foreach ($unidades as $unidad) {
            if (!in_array($unidad->proyectoTipoUnidad->tipoUnidad, $tiposUnidades)) {
                $tiposUnidades []= $unidad->proyectoTipoUnidad->tipoUnidad;
            }
        }
        return $view->render($response, 'ventas.propiedades.edit', compact('propiedad',
            'proyecto', 'tiposUnidades', 'unidades', 'venta'));
    }
    public function pie(ServerRequestInterface $request, ResponseInterface $response, View $view,
                        Service\Venta $service, int $venta_id): ResponseInterface
    {
        $venta = $service->getById($venta_id);
        return $view->render($response, 'ventas.pies.edit', compact('venta'));
    }
    public function add(ServerRequestInterface $request, ResponseInterface $response, View $view,
                        Repository\Region $regionRepository, Repository\Proyecto $proyectoRepository): ResponseInterface
    {
        $regiones = $regionRepository->fetchAll();
        usort($regiones, function(Model\Region $a, Model\Region $b) {
            return $a->numeracion - $b->numeracion;
        });
        $proyectos = $proyectoRepository->fetchAllActive();
        return $view->render($response, 'ventas.add', compact('regiones', 'proyectos'));
    }
    public function cuotas(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
                           Service\Contabilidad\Banco $bancoService,
                           Repository\Venta\TipoEstadoPago $tipoEstadoPagoRepository,
                           View $view, int $venta_id): ResponseInterface
    {
        $venta = $ventaService->getById($venta_id);
        $asociadas = [];
        if (isset($venta->formaPago()->pie->asociado)) {
            $asociadas []= $ventaService->getByPie($venta->formaPago()->pie->asociado->id);
            foreach ($venta->formaPago()->pie->asociado->asociados() as $asociado) {
                if ($venta->formaPago()->pie->id === $asociado->id) {
                    continue;
                }
                $asociadas []= $ventaService->getByPie($asociado->id);
            }
        }
        if (count($venta->formaPago()->pie->asociados()) > 0) {
            foreach ($venta->formaPago()->pie->asociados() as $asociado) {
                if ($asociado->id === $venta->formaPago()->pie->id) {
                    continue;
                }
                $asociadas []= $ventaService->getByPie($asociado->id);
            }
        }
        $bancos = $bancoService->getAll('nombre');
        $estados = $tipoEstadoPagoRepository->fetchAll('descripcion');
        return $view->render($response, 'ventas.pies.cuotas', compact('venta', 'asociadas', 'bancos', 'estados'));
    }
    public function escriturar(ServerRequestInterface        $request, ResponseInterface $response, Service\Venta $ventaService,
                               Repository\Contabilidad\Banco $bancoRepository, View $view, int $venta_id): ResponseInterface
    {
        $venta = $ventaService->getById($venta_id);
        $bancos = $bancoRepository->fetchAll();
        usort($bancos, function(Model\Contabilidad\Banco $a, Model\Contabilidad\Banco $b) {
            return strcmp($a->nombre, $b->nombre);
        });
        return $view->render($response, 'ventas.escriturar', compact('venta', 'bancos'));
    }
    public function desistir(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
                             View $view, int $venta_id): ResponseInterface
    {
        $venta = $ventaService->getById($venta_id);
        return $view->render($response, 'ventas.desistir', compact('venta'));
    }
    public function desistida(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
                              View $view, int $venta_id): ResponseInterface
    {
        $venta = $ventaService->getById($venta_id);
        return $view->render($response, 'ventas.desistida', compact('venta'));
    }
}
