<?php

namespace App\Models;

use App\Utils\TransporteUtils;

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);
    }

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

    /**
     * Los productos del pedido que no aportan para el
     * bono de transporte
     */
    function productosSinTransporte() {
        return $this->productos()->orWhere(['bono' => true, 'barrial' => true]);
    }

    /**
     * Los productos del pedido que aportan para el
     * bono de transporte.
     */
    function productosConTransporte() {
        return $this->productos()->where(['bono' => false, 'barrial' => false]);
    }

    /**
     * Los productos no barriales del pedido. 
     */
    function productosNoBarriales() {
        return $this->productos()->where('barrial',false);
    }

    /**
     * Los bonos del pedido.
     */
    function bonos() {
        return $this->productos()->where('bono',true);
    }

    /**
     * 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.
     */
    function total($productos = null) : float {
        if (!$productos)
            $productos = $this->productos();

        return $productos->sum(fn($p) => $p->price * $p->pivot->cantidad);
    }

    /**
     * El total de bonos de transporte del pedido
     */
    function totalTransporte() : int {
        if ($this->productos()->every(fn($prod) => !$prod->pagaTransporte())) 
            return 0;
        
        return TransporteUtils::total($this->productosConTransporte());
    }

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

    function toggleConfirm() : bool {
        $this->confirmed = !$this->confirmed;
        $this->save();
        return $this->confirmed;
    }

    function agregarProducto(Producto $producto, int $cantidad) {
        $productoEnChismosa = $this->productos()->where('id', $producto->id)->first();
        if ($productoEnChismosa) {
            $productoEnChismosa->pivot->cantidad += $cantidad;
            $productoEnChismosa->save();
        } else {
            $this->productos()->attach($producto, ['cantidad' => $cantidad]);
        }
    }

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