<?php

namespace App\Observers;

use App\Jobs\ElaboraJobStampa;
use App\Models\Ordine;
use App\Models\PrintJob;
use App\Models\Cucina;
use Illuminate\Support\Facades\Log;
use App\Models\SaltacodaOrdine;

class OrdineObserver
{
    /**
     * Handle the Ordine "created" event.
     */
    public function created(Ordine $ordine): void
    {
        //
    }

    /**
     * Handle the Ordine "updated" event.
     */
    public function updated(Ordine $ordine): void
    {
        // VERIFICA SE LO STATO DELL'ORDINE È CAMBIATO E SE È PAGATO IN CASO DI PRENOTAZIONE !!!!!!
        if (! $ordine->wasChanged('stato') || $ordine->stato !== Ordine::PAGATO) {
            return;
        }

        //Aggiorna lo stato del pre_ordine
        $preOrdineId = data_get($ordine->info, 'pre_ordine_id');
        $preOrdineCodice = data_get($ordine->info, 'pre_ordine_codice');

        if ($preOrdineId || $preOrdineCodice) {
            $preOrdineQuery = SaltacodaOrdine::query()
                ->where('stato', SaltacodaOrdine::PRE_CARRELLO);

            if ($preOrdineId) {
                $preOrdineQuery->where('id', $preOrdineId);
            } else {
                $preOrdineQuery->where('codice', $preOrdineCodice);
            }

            $preOrdineQuery->update(['stato' => SaltacodaOrdine::IMPORTATO]);
        }
        
        //Crea il print job per lo scontrino
        $printJob = PrintJob::query()->firstOrNew([
            'ordine_id' => $ordine->id,
            'tipo' => PrintJob::TIPO_SCONTRINO,
        ]);

        if (
            $printJob->exists
            && in_array($printJob->stato, [
                PrintJob::STATO_IN_CODA,
                PrintJob::STATO_PRESO,
                PrintJob::STATO_COMPLETATO,
            ], true)
        ) {
            return;
        }

        $printJob->fill([
            'dispositivo_id' => $ordine->dispositivo_id,
            'stampante_id' => $ordine->dispositivo->url_stampante,
            'stato' => PrintJob::STATO_IN_ATTESA,
            'payload' => null,
        ]);
        $printJob->save();

        ElaboraJobStampa::dispatch($printJob->id);

        //Crea comande cucine
        $cucine = $ordine->cucine();
        foreach($cucine as $cucina){
            $printJob = PrintJob::query()->firstOrNew([
                'ordine_id' => $ordine->id,
                'tipo' => PrintJob::tipoComandaCucina($cucina),
            ]);
            if (
                $printJob->exists
                && in_array($printJob->stato, [
                    PrintJob::STATO_IN_CODA,
                    PrintJob::STATO_PRESO,
                    PrintJob::STATO_COMPLETATO,
                ], true)
            ) {
                continue;
            }
            $cucinaModel = Cucina::find($cucina);
            if ($cucinaModel === null) {
                Log::error('Cucina non trovata id: '.$cucina);
                throw new \RuntimeException('Cucina non trovata id: '.$cucina);
            }elseif($cucinaModel->stampante_id === null){
                Log::warning('Stampante non trovata per la cucina '.$cucina.' ordine: '.$ordine->id);
                // throw new \RuntimeException('Stampante non trovata per la cucina '.$cucina);
            }

            $printJob->fill([
                'dispositivo_id' => $ordine->dispositivo_id,
                'stampante_id' => $cucinaModel->stampante_id,
                'stato' => PrintJob::STATO_IN_ATTESA,
                'payload' => null,
            ]);
            $printJob->save();
            ElaboraJobStampa::dispatch($printJob->id);
        }

        //Aggiorna il utilizzo del dispositivo
        app('\App\Services\Fatturazione\RigaFatturazioneService')->aggiornaUtilizzoDispositivo($ordine->dispositivo_id);

        //Crea l'asporto se l'ordine è asporto
        if (isset($ordine->info['asporto']) && $ordine->info['asporto'] == true) {
            app('\App\Services\Asporto\AsportoService')->creaAsporto($ordine);
        }
   
    }

    /**
     * Handle the Ordine "deleted" event.
     */
    public function deleted(Ordine $ordine): void
    {
        //
    }

    /**
     * Handle the Ordine "restored" event.
     */
    public function restored(Ordine $ordine): void
    {
        //
    }

    /**
     * Handle the Ordine "force deleted" event.
     */
    public function forceDeleted(Ordine $ordine): void
    {
        //
    }
}
