<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Dispositivo;
use App\Models\MonitorHasContenuto;
use App\Models\RigaOrdine;
use App\Services\notifica\NotificaOrdineService;
use Illuminate\Support\Facades\Log;

class RigaOrdineController extends Controller
{
    public static $permission_group = "Riga Ordine";
    public static $permissions = [
        'view-riga_ordine' => 'Vedi',
        'create-riga_ordine' => 'Crea',
        'edit-riga_ordine' => 'Modifica',
        'delete-riga_ordine' => 'Elimina',
    ];
    
    public static function middleware(): array
    {
        return [
            new Middleware('permission:view-riga_ordine', only: ['index']),
            new Middleware('permission:create-riga_ordine|edit-riga_ordine|delete-riga_ordine', only: ['store', 'update', 'destroy']),
        ];
    }

    public function dettagli(Request $request){
        if($request->has('riga_ordine_id')){
            $riga_ordine = RigaOrdine::find($request->riga_ordine_id);
            if($riga_ordine == null){ return response()->json(['success' => false, 'message' => 'Riga ordine non trovata']); }
            return view('punto_vendita.cassa._partials.carrello.cmd_carrello', ['cmd' => 'dettagli', 'riga_ordine_id' => $riga_ordine->id]);
        }
        return response()->json(['success' => false, 'message' => 'ID non valido']);
        
    }

    public function lista_da_chiamare(Request $request){
        [$attivitaId, $dispositivo, $cucinaId, $errorResponse] = $this->resolveOperatoreContext($request);
        if($errorResponse){
            return $errorResponse;
        }

        $range = $request->get('range', '1h');

        $righeQuery = RigaOrdine::query()
            ->with(['piatto', 'ordine'])
            ->where('stato', RigaOrdine::ORDINATO)
            ->whereHas('piatto', function($query) use ($cucinaId){
                $query->where('cucina_id', $cucinaId);
            })
            ->whereHas('ordine', function($query) use ($attivitaId){
                $query->where('attivita_id', $attivitaId);
            })
            ->orderBy('created_at', 'asc');

        $this->applyRangeFilter($righeQuery, $range, 'created_at');
        $righe = $righeQuery->get();

        return response()->json([
            'success' => true,
            'range' => $range,
            'data' => $righe->map(function($riga){
                return [
                    'id' => $riga->id,
                    'ordine_id' => $riga->ordine_id,
                    'piatto' => $riga->piatto?->nome ?? 'Piatto',
                    'quantita' => $riga->quantita,
                    'stato' => $riga->stato,
                ];
            })->values(),
        ]);
    }

    public function lista_chiamate(Request $request){
        // dd($request->all());
        [$attivitaId, $dispositivo, $cucinaId, $errorResponse] = $this->resolveOperatoreContext($request);
        if($errorResponse){
            return $errorResponse;
        }

        $range = $request->get('range', '1h');

        $righeQuery = RigaOrdine::query()
            ->with(['piatto', 'ordine'])
            ->where('stato', RigaOrdine::CHIAMATO)
            ->whereHas('piatto', function($query) use ($cucinaId){
                $query->where('cucina_id', $cucinaId);
            })
            ->whereHas('ordine', function($query) use ($attivitaId){
                $query->where('attivita_id', $attivitaId);
            })
            ->orderBy('updated_at', 'desc');

        $this->applyRangeFilter($righeQuery, $range, 'updated_at');
        $righe = $righeQuery->get();

        return response()->json([
            'success' => true,
            'range' => $range,
            'data' => $righe->map(function($riga){
                return [
                    'id' => $riga->id,
                    'ordine_id' => $riga->ordine_id,
                    'piatto' => $riga->piatto?->nome ?? 'Piatto',
                    'quantita' => $riga->quantita,
                    'stato' => $riga->stato,
                ];
            })->values(),
        ]);
    }

    public function chiamata(Request $request){
        [$attivitaId, $dispositivo, $cucinaId, $errorResponse] = $this->resolveOperatoreContext($request);
        if($errorResponse){
            return $errorResponse;
        }

        $riga_ordine = RigaOrdine::with(['piatto', 'ordine'])->find($request->riga_ordine_id);
        if(!$riga_ordine){
            return response()->json(['success' => false, 'message' => 'Riga ordine non trovata'], 404);
        }

        if(!$riga_ordine->piatto || (int) $riga_ordine->piatto->cucina_id !== (int) $cucinaId){
            return response()->json(['success' => false, 'message' => 'Riga ordine non di competenza della cucina del dispositivo'], 403);
        }

        if(!$riga_ordine->ordine || (int) $riga_ordine->ordine->attivita_id !== (int) $attivitaId){
            return response()->json(['success' => false, 'message' => 'Riga ordine non appartenente all\'attività'], 403);
        }

        if($riga_ordine->stato !== RigaOrdine::ORDINATO){
            return response()->json(['success' => false, 'message' => 'Transizione non valida'], 422);
        }

        $riga_ordine->stato = RigaOrdine::CHIAMATO;
        $riga_ordine->save();

Log::info('riga ordine chiamata', [
    'ordine_id' => $riga_ordine->ordine->id,
    'fcm_token' => $riga_ordine->ordine->fcm_token,
]);
        //Invia notifica, se fcm salvato da utente
        if($riga_ordine->ordine->fcm_token){
            Log::info('fcm token trovato', [
                'ordine_id' => $riga_ordine->ordine->id,
                'fcm_token' => $riga_ordine->ordine->fcm_token,
            ]);
            app(\App\Services\Notifica\NotificaOrdineService::class)->inviaOrdinePronto(
                $riga_ordine,
                'Ordine pronto',
                ($riga_ordine->piatto?->nome ?? 'Piatto').' — ritira al banco'
            );
       
        }
        return response()->json(['success' => true, 'message' => 'Riga ordine chiamata']);
    }

    public function ritiro(Request $request){
        [$attivitaId, $dispositivo, $cucinaId, $errorResponse] = $this->resolveOperatoreContext($request);
        if($errorResponse){
            return $errorResponse;
        }

        $riga_ordine = RigaOrdine::with(['piatto', 'ordine'])->find($request->riga_ordine_id);
        if(!$riga_ordine){
            return response()->json(['success' => false, 'message' => 'Riga ordine non trovata'], 404);
        }

        if(!$riga_ordine->piatto || (int) $riga_ordine->piatto->cucina_id !== (int) $cucinaId){
            return response()->json(['success' => false, 'message' => 'Riga ordine non di competenza della cucina del dispositivo'], 403);
        }

        if(!$riga_ordine->ordine || (int) $riga_ordine->ordine->attivita_id !== (int) $attivitaId){
            return response()->json(['success' => false, 'message' => 'Riga ordine non appartenente all\'attività'], 403);
        }

        if($riga_ordine->stato !== RigaOrdine::CHIAMATO){
            return response()->json(['success' => false, 'message' => 'Transizione non valida'], 422);
        }

        $riga_ordine->stato = RigaOrdine::RITIRATO;
        $riga_ordine->save();

        return response()->json(['success' => true, 'message' => 'Riga ordine ritirata']);
    }

    private function resolveOperatoreContext(Request $request): array{
        $attivitaId = $request->attivita_id ?? session('attivita_attuale');
        if(!$attivitaId){
            return [null, null, null, response()->json(['success' => false, 'message' => 'Attività non trovata'], 404)];
        }

        $dispositivo = Dispositivo::find($request->dispositivo_id);
        if(!$dispositivo){
            return [null, null, null, response()->json(['success' => false, 'message' => 'Dispositivo non trovato'], 404)];
        }

        if((int) $dispositivo->attivita_id !== (int) $attivitaId){
            return [null, null, null, response()->json(['success' => false, 'message' => 'Dispositivo non appartenente all\'attività'], 403)];
        }

        $cucinaId = $dispositivo->cucina_id;
        if($dispositivo->tipo === Dispositivo::MONITOR){
            $monitorHasContenuto = MonitorHasContenuto::query()
                ->where('monitor_id', $dispositivo->id)
                ->first();

            if(!$monitorHasContenuto || !$monitorHasContenuto->cucina_id){
                return [null, null, null, response()->json(['success' => false, 'message' => 'Monitor non associato a una cucina'], 422)];
            }

            $cucinaId = $monitorHasContenuto->cucina_id;
        }

        if(!$cucinaId){
            return [null, null, null, response()->json(['success' => false, 'message' => 'Dispositivo non associato a una cucina'], 422)];
        }

        return [$attivitaId, $dispositivo, $cucinaId, null];
    }

    private function applyRangeFilter(Builder $query, string $range, string $column): void{
        switch($range){
            case '3h':
                $query->where($column, '>=', now()->subHours(3));
                break;
            case 'today':
                $query->whereBetween($column, [now()->startOfDay(), now()->endOfDay()]);
                break;
            case '1h':
            default:
                $query->where($column, '>=', now()->subHour());
                break;
        }
    }




    // public function index(RigaOrdineDataTable $dataTable){
    //     return $dataTable->render('riga_ordine.index');
    // }

    // public function datatable(RigaOrdineDataTable $dataTable){
    //     return $dataTable->render('punto_vendita.cassa._partials.carrello.index');
    // }

}
