<?php

namespace App\Http\Livewire;

use App\Models\Impresora;
use App\Models\Movimiento;
use App\Models\Pedido;
use App\Models\Producto;
use App\Models\Ruta;
use App\Printer\PrinterHandler;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Livewire\Component;
use Livewire\WithPagination;

class PedidoController extends Component
{
    use WithPagination;
    public $buscador ="", $buscadorProducto = "" ,$modal = false, $modalPedido = false;

    public $pedido, $productos = [],$totalPagar = 0, $IVA = 0, $ventaEspecial;
    public $pago_efectivo, $cambio;
    public $totals = [];
    protected $rules =[
        'productos.*.linea' => 'required',
        'productos.*.codigo' => 'required',
        'productos.*.descripcion' => 'required',
        'productos.*.ruta_id' => 'required',
        'productos.*.cantidad' => 'required',
        'productos.*.precio_unitario' => 'required',
        'pedido.cuenta' => 'required',
        'pedido.folio_proveedor' => 'required',
        'pedido.telefono' => 'required',
        'pedido.year' => 'required',
        'pedido.marca' => 'required',
        'pedido.modelo' => 'required',
        'pedido.motor' => 'required',
        'pedido.user_id' => 'required',
        'pedido.comentarios' => 'required',
        'pedido.numero_remision' => 'required',
        'totals.*' => 'required',
        'ventaEspecial.codigo' => 'min:0',
        'ventaEspecial.pago_efectivo' => 'numeric',
        'ventaEspecial.pago_tarjeta' => 'numeric',
        'ventaEspecial.pago_vales' => 'numeric',
        'ventaEspecial.precio_venta' => 'numeric',
        'ventaEspecial.pago_transferencia' => 'numeric',
        'ventaEspecial.nota_credito' => 'numeric',
        'ventaEspecial.estado_movimiento_id' => 'numeric',
    ];

    protected $messages = [
        'productos.*.linea.required' => 'Campo obligatorio.',
        'productos.*.codigo.required' => 'Campo obligatorio.',
        'productos.*.descripcion.required' => 'Campo obligatorio.',
        'productos.*.ruta_id.required' => 'Campo obligatorio.',
        'productos.*.cantidad.required' => 'Campo obligatorio.',
        'productos.*.precio_unitario.required' => 'Campo obligatorio.',
        'productos.*.unidades.required' => 'Campo obligatorio.',

        'productos.*.linea.max' => 'Campo debe ser menor a :max.',
        'productos.*.codigo.max' => 'Campo debe ser menor a :max.',
        'productos.*.descripcion.max' => 'Campo debe ser menor a :max.',
        'productos.*.ruta_id.max' => 'Campo debe ser menor a :max.',
        'productos.*.cantidad.max' => 'Campo debe ser menor a :max.',
        'productos.*.precio_unitario.max' => 'Campo debe ser menor a :max.',
    ];

    protected $listeners = ['agregar','save','saveArrivo','cerrarVenta','entregarVenta'];

    public function render()
    {
        if($this->buscador != "")
        {
            $pedidos = Pedido::where('pedido','like','%'.$this->buscador.'%')
                ->orderBy('is_venta_cerrada','asc')
                ->orderBy('is_venta_entregada','asc')
                ->orderBy('id','desc')
                ->paginate(10);
        }
        else
        {
            $pedidos = Pedido::Where('user_id',"=",auth()->user()->id)
            ->orderBy('is_venta_cerrada','ASC')
            ->orderBy('is_venta_entregada','ASC')
            ->orderBy('id','desc')
                ->paginate(10);
        }
        return view('pedido.pedido',[
            // 'pedidos' => Pedido::where('pedido','like','%'.$this->buscador.'%')->orWhere('user_id',"=",auth()->user()->id)->orderBy('id','desc')->paginate(10),
            'pedidos' => $pedidos,
            'productosList' => Producto::where('descripcion','like','%'.$this->buscadorProducto.'%')
                                ->orWhere('codigo','like','%'.$this->buscadorProducto.'%')->paginate(10),
            'rutas' => Ruta::all(),
        ]);
    }

    public function create()
    {
        $this->reset();
        $this->pago_efectivo = 0;
        $this->cambio = 0;
        $this->pedido = new Pedido();
        $this->ventaEspecial = new Movimiento([
            'codigo' => 0,
            'pago_efectivo' => 0,
            'pago_tarjeta' => 0,
            'pago_vales' => 0,
            'pago_transferencia' => 0,
            'nota_credito' => 0,
            'precio_venta' => 0,
            'estado_movimiento_id' => VentaEspecialController::CODIGO_VENTA_ESPECIAL,

        ]);
        $this->showModal();
    }

    public function agregar($id = '')
    {
        // if(auth()->user()->hasRole('admin'))
        $this->buscadorProducto = '';
        $this->productos[] = Producto::firstOrNew(['id' => $id]);
        $this->totals[] = 0;
        $this->emit('addProductEvent');
    }

    public function agregarProductoArrivo($id = '')
    {
        if(auth()->user()->hasRole('admin'))
        {
            $this->buscadorProducto = '';
            $this->productos[] = Producto::firstOrNew(['id' => $id]);
            $this->totals[] = 0;
            $this->emit('addProductEvent');
        }
    }
    
    public function total($id)
    {
        return ((key_exists('cantidad',$this->productos[$id]) && key_exists('precio_unitario',$this->productos[$id]) ) && 
        (is_numeric($this->productos[$id]['cantidad']) && is_numeric($this->productos[$id]['precio_unitario'])))
        ?$this->productos[$id]['cantidad'] * $this->productos[$id]['precio_unitario']
        :'0';
    }

    public function updatedPagoEfectivo($value)
    {
        if($value)
        {
            $this->cambio = $this->pago_efectivo - $this->ventaEspecial->pago_efectivo;
        }
    }


    public function updatedProductos($value, $key)
    {
        $key = intval(explode('.',$key)[0]);
        $this->totals[$key] = $this->total($key);
        if($this->totals[$key] != 0)
        {
            $this->updateTotal($this->totals);
        }
    }

    public function updateTotal($totals)
    {
        $total = array_sum(array_filter($totals,'is_numeric'));
        $this->totalPagar = $total/1.08;
        $this->IVA = $this->totalPagar*0.08;
        $this->totalPagar += $this->IVA;
    }

    public function updatedModal()
    {
        if(!$this->modal){
            $this->clearInputs();
        }
    }

    public function updatedModalPedido()
    {
        if(!$this->modalPedido){
            $this->clearInputs();
        }
    }

    public function show(Pedido $pedido)
    {
        // dd($pedido->is_venta_cerrada,$pedido->is_venta_entregada);
        $this->totalPagar = 0;
        $this->IVA = 0;
        $this->pedido = $pedido;
        foreach ($this->pedido->productos as $producto) {
            $producto->unidades = $producto->pivot->unidades;
            $producto->precio_unitario = $producto->pivot->precio_unitario;
            $producto->producto_id = $producto->pivot->producto_id;
            $producto->is_arrivo = $producto->pivot->is_arrivo;
            $this->productos[] = $producto;
            $this->totalPagar+= ($producto->pivot->unidades*$producto->pivot->precio_unitario);
        }

        $this->totalPagar/= 1.08;
        $this->IVA = $this->totalPagar*0.08;
        $this->totalPagar += $this->IVA;
        
        $this->showModal('modalPedido');
    }
    public function save()
    {
        if(!$this->productos)
        {
            return;
        }
        $this->pedido->user_id = auth()->user()->id;
        $this->validate([
            'pedido.cuenta' => 'required',
            'pedido.telefono' => 'required',
            'pedido.year' => 'required',
            'pedido.marca' => 'required',
            'pedido.modelo' => 'required',
            'pedido.motor' => 'required',
            'productos.*.linea' => 'required|max:20',
            'productos.*.codigo' => 'required|max:20',
            'productos.*.descripcion' => 'required|max:100',
            'productos.*.ruta_id' => 'required',
            'productos.*.cantidad' => 'required|max:4',
            'productos.*.precio_unitario' => 'required|max:8',

            'ventaEspecial.pago_efectivo' => 'numeric',
            'ventaEspecial.pago_tarjeta' => 'numeric',
            'ventaEspecial.pago_vales' => 'numeric',
            'ventaEspecial.pago_transferencia' => 'numeric',
            'ventaEspecial.nota_credito' => 'numeric',
            'ventaEspecial.estado_movimiento_id' => 'numeric',
        ]);

        $this->pedido->is_venta_cerrada = 0;
        $this->pedido->is_venta_entregada = 0;

        $this->pedido->save();

        $this->ventaEspecial->user_id = auth()->user()->id;
        $this->ventaEspecial->precio_venta = $this->totalPagar;
        $this->ventaEspecial->codigo = $this->pedido->pedido;
        $this->ventaEspecial->save();
        // $this->ventaEspecial->save();

        foreach ($this->productos as $producto) {
            $productoCreated = Producto::firstOrCreate(
                ['linea' => $producto['linea'], 'codigo' => $producto['codigo']],
                [
                    'linea' => $producto['linea'],
                    'codigo' => $producto['codigo'],
                    'descripcion' => $producto['descripcion'],
                    'ruta_id' => $producto['ruta_id'],
                    'precio_unitario' => $producto['precio_unitario'],
                ]
            );

            $productoCreated->precio_unitario = $producto['precio_unitario'];
            $productoCreated->save();

            $this->pedido->productos()->attach($productoCreated->id,['unidades' => $producto['cantidad'], 'precio_unitario' => $producto['precio_unitario'], 'is_arrivo' => false]);
        }
        $this->pedido->cambio = $this->cambio;
        $this->imprimirTicket($this->pedido);
        $this->imprimirTicket($this->pedido,false);
        session()->flash('message','El pedido se ha generado correctamente.');
        $this->closeModal();
        $this->clearInputs();
    }

    public function entregarVenta()
    {
        $this->pedido->is_venta_entregada = true;
        $this->pedido->venta_entregada_user_id = auth()->user()->id;
        $this->pedido->venta_entregada_at = Carbon::now();
        $this->pedido->save();

        $this->closeModal('modalPedido');
        session()->flash('message','El pedido se ha entregado correctamente.');
        $this->clearInputs();
    }

    public function cerrarVenta()
    {
        if(!$this->pedido->is_venta_entregada)
        {
            session()->flash('error','No puedes cerrar la venta si no la has entregado.');
            $this->closeModal('modalPedido');
            return;
        }
        $this->pedido->is_venta_cerrada = true;
        $this->pedido->venta_cerrada_user_id = auth()->user()->id;
        $this->pedido->venta_cerrada_at = Carbon::now();
        $this->pedido->save();

        $this->closeModal('modalPedido');
        session()->flash('message','El pedido se ha cerrado correctamente.');
        $this->clearInputs();
    }

    public function saveArrivo()
    {
        if(auth()->user()->hasRole('admin'))
        {
            $this->validate([
                'pedido.cuenta' => 'required',
                'pedido.telefono' => 'required',
                'pedido.year' => 'required',
                'pedido.marca' => 'required',
                'pedido.modelo' => 'required',
                'pedido.motor' => 'required',
                'productos.*.linea' => 'required|max:20',
                'productos.*.codigo' => 'required|max:20',
                'productos.*.descripcion' => 'required|max:100',
                'productos.*.ruta_id' => 'required',
                'productos.*.unidades' => 'required|max:10',
                'productos.*.precio_unitario' => 'required|max:8',
            ]);

            foreach ($this->productos as $index => $producto) {
                $productoCreado = Producto::updateOrCreate(
                    ['id' => $producto['id']??""],
                    [
                       'linea' => $producto['linea'], 
                       'codigo' => $producto['codigo'], 
                       'descripcion' => $producto['descripcion'], 
                       'ruta_id' => $producto['ruta_id'], 
                       'precio_unitario' => $producto['precio_unitario'], 
                    ]
                );
                $this->productos[$index]['producto_id'] = $productoCreado->id;
                $this->productos[$index]['id'] = $productoCreado->id;
            }
        }

        
        // if(auth()->user()->hasRole('admin'))
        // {
            $this->validate([
                'pedido.cuenta' => 'required',
                'pedido.telefono' => 'required',
                'pedido.year' => 'required',
            ]);

            $this->pedido->save();
            $productosSync = [];
            foreach ($this->productos as $producto) {
                $productosSync[$producto['id']] = [
                    'unidades' => $producto['unidades'],
                    'precio_unitario' => $producto['precio_unitario'],
                    'is_arrivo' => $producto['is_arrivo'] ?? 0
                ];
            }
            $this->pedido->productos()->sync($productosSync);
            
            session()->flash('message','El pedido se ha actualizado correctamente.');
        // }
        $this->closeModal('modalPedido');
        $this->clearInputs();
    }

    public function delete(Pedido $pedido)
    {
        if(auth()->user()->hasRole('admin'))
        {
            $pedido->productos()->detach();
            $pedido->delete();
            session()->flash('message','El pedido se ha eliminado correctamente.');
        }
    }

    public function eliminarProducto($id)
    {
        unset($this->productos[$id]);
        unset($this->totals[$id]);
    }

    public function imprimirTicket(Pedido $pedido,$hashed = true)
    {
        // foreach ($pedido->productos as $producto) {
        // dd('Codigo:'.$producto->codigo.' desc:'.substr($producto->descripcion,0,11).' Cant:'.$producto->pivot->unidades.' Total:'.round($producto->pivot->unidades*$producto->pivot->precio_unitario/1.16,2));
        //     // dd($producto->pivot);
        // }
        // try {
            $impresora = Impresora::findOrFail(auth()->user()->impresora_id);
            $printer = new PrinterHandler($impresora,$impresora->is_compartida?PrinterHandler::PRINTER_BY_SHARED:PrinterHandler::PRINTER_BY_IP);
            $printer->printPedido($pedido,$hashed);
            $printer->feed();
            $printer->cut();
            $printer->close();
        // } catch (\Throwable $th) {
            // throw $th;
        // }
    }

    public function showModal($modal = 'modal')
    {
        $this->{$modal} = true;
    }

    public function closeModal($modal = 'modal')
    {
        $this->{$modal} = false;
    }

    public function clearInputs()
    {
        $this->reset();
    }
}
