<?php

namespace App\Models;

use App\Utils\TransporteUtils;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Model;

class Pedido extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'nombre',  'pagado', 'terminado'
    ];

    /**
     * El barrio al que pertenece el pedido.
     */
    public function barrio(): BelongsTo {
        return $this->belongsTo(Barrio::class);
    }

    public function togglePagado() : bool {
        $this->pagado = !$this->pagado;
        $this->save();
        return $this->pagado;
    }

    public function toggleTerminado() : bool {
        $this->terminado = !$this->terminado;
        $this->save();
        return $this->terminado;
    }

    /**
     * Los productos que pertenecen al pedido.
     */
    public function productos(): BelongsToMany {
        return $this->belongsToMany(Producto::class)->withPivot(['cantidad']);
    }

    public function productosConTransporte() : Collection
    {
        return $this->productos()->where(fn($p) => $p->pagaTransporte())->get();
    }

    public function agregarProducto(Producto $producto, int $cantidad) : Producto {
        $productoEnChismosa = $this->productos()->find($producto->id);
        if ($productoEnChismosa) {
            $productoEnChismosa->pivot->cantidad += $cantidad;
            if ($productoEnChismosa->pivot->cantidad != 0)
                $productoEnChismosa->save();
            else
                $this->quitarProducto($producto);
            return $productoEnChismosa;
        } else {
            $this->productos()->attach($producto, ['cantidad' => $cantidad]);
            return $this->productos()->find($producto->id);
        }
    }

    public function quitarProducto(Producto $producto) {
        $this->productos()->detach($producto);
    }

    /**
     * El total de los productos del pedido
     * sumado al total de los bonos de transporte
     */
    public function totalATransferir() : float {
        return $this->totalProductos() + $this->totalBonosDeTransporte();
    }

    /**
     * Toma como parámetro una colección de productos
     * y devuelve la suma de los totales (precio * cantidad)
     * de cada uno.
     *
     * Si la colección es null o no se pasa ningún parámetro
     * se toman todos los productos del pedido.
     */
    private function totalProductos($productos = null) {
        if (!$productos)
            $productos = $this->productos()->get();

        return $productos->map(
            fn($producto) => $producto->precio * $producto->pivot->cantidad
        )->sum();
    }

    /**
     * El total de bonos de transporte del pedido
     */
    public function totalBonosDeTransporte() : int {
        return TransporteUtils::calcularTotal(
            $this->totalProductos($this->productosConTransporte())
        );
    }
}