<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Ordine;
use App\Models\PuntoVendita;
use App\Models\Attivita;
use App\Models\Dispositivo;
use App\Models\Pagamento;
use App\Models\MetodoPagamento;
use App\Models\RigaOrdine;
use App\DataTables\RigaOrdineDataTable;
use App\Models\Piatto;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use App\Http\Controllers\PagamentoController;
use App\Services\Carrello\CarrelloService;

class CarrelloController extends Controller
{

    private CarrelloService $carrelloService;

    public function __construct(CarrelloService $carrelloService)
    {
        $this->carrelloService = $carrelloService;
    }

    public function index(){
        // return Ordine::all();
        return Ordine::where('stato', Ordine::CARRELLO)->get();
    }


    public function list(Request $request, RigaOrdineDataTable $dataTable){
        $ordine = Ordine::where([
            'stato' => Ordine::CARRELLO, 
            'dispositivo_id' => Session::get('dispositivo_id') || $request->dispositivo_id,
            'attivita_id' => Session::get('attivita_id') || $request->attivita_id,
        ])->orderBy('created_at', 'desc')->first();
    // dd($ordine->count());
        return $dataTable->render('punto_vendita.cassa._partials.carrello.index', ['ordine' => $ordine]);
    }


    public function aumenta(Request $request){
        $request->validate([
            'ordine_id' => 'nullable|integer',
            'piatto_id' => 'required|integer|exists:piatto,id',
            'dispositivo_id' => 'required|integer|exists:dispositivo,id',
            'attivita_id' => 'nullable|integer|exists:attivita,id',
            'riga_ordine_id' => 'nullable|integer|exists:riga_ordine,id',
        ]);
       
       $result = $this->carrelloService->aumentaQuantita($request->dispositivo_id, $request->attivita_id, $request->ordine_id, $request->piatto_id, $request->riga_ordine_id);
       $carrello = $result['ordine'];
       $riga = $result['riga'];

       return response()->json([
           'success' => true,
           'message' => 'Quantità aumentata',
           'ordine_id' => $carrello->id,
           'data' => $riga,
       ]);


        // Tolleranza su ordine_id stale: se non e` valido, usa/crea il carrello corrente per dispositivo+attivita.
        // $carrelloBaseQuery = Ordine::query()
        //     ->where('stato', Ordine::CARRELLO)
        //     ->where('dispositivo_id', $request->dispositivo_id)
        //     ->when(
        //         $request->filled('attivita_id'),
        //         fn ($q) => $q->where('attivita_id', $request->attivita_id)
        //     );

        // $carrello = null;
        // if ($request->filled('ordine_id')) {
        //     $carrello = (clone $carrelloBaseQuery)
        //         ->whereKey($request->ordine_id)
        //         ->first();
        // }

        // if (!$carrello) {
        //     $carrello = (clone $carrelloBaseQuery)->latest('id')->first();
        // }

        // if (!$carrello) {
        //     $carrello = Ordine::create([
        //         'stato' => Ordine::CARRELLO,
        //         'dispositivo_id' => $request->dispositivo_id,
        //         'attivita_id' => $request->attivita_id,
        //     ]);
        // }

        // $riga = RigaOrdine::where('ordine_id', $carrello->id)->where('piatto_id', $request->piatto_id)->first();
        // if($riga){
        //     $riga->quantita += 1;
        //     $riga->prezzo = Piatto::find($request->piatto_id)->prezzo*$riga->quantita;
        //     $riga->save();
        // }else{
        //     $riga = RigaOrdine::create([
        //         'ordine_id' => $carrello->id,
        //         'piatto_id' => $request->piatto_id,
        //         'quantita' => 1,
        //         'prezzo' => Piatto::find($request->piatto_id)->prezzo,
        //     ]);
        // }
        // dd($riga);

    }

    public function diminuisci(Request $request){
        $request->validate([
            'ordine_id' => 'required|integer|exists:ordine,id',
            'piatto_id' => 'required|integer|exists:piatto,id',
            'riga_ordine_id' => 'required|integer|exists:riga_ordine,id',
        ]);
        $result = $this->carrelloService->diminuisciQuantita($request->ordine_id, $request->piatto_id, $request->riga_ordine_id);
        return response()->json([
            'success' => true,
            'message' => 'Quantità diminuita',
            'ordine_id' => $result['ordine']->id,
            'data' => $result['riga'],
        ]);
        // $carrello = Ordine::find($request->ordine_id);
        // $riga = RigaOrdine::where('ordine_id', $carrello->id)->where('piatto_id', $request->piatto_id)->first();
        // if($riga){
        //     $riga->quantita -= 1;
        //     $riga->prezzo = Piatto::find($request->piatto_id)->prezzo*$riga->quantita;
        //     $riga->save();
        // }
        // return response()->json([
        //     'success' => true,
        //     'message' => 'Quantità diminuita',
        //     'data' => $riga,
        // ]);
    }


    public function elimina(Request $request){
        $request->validate([
            'riga_ordine_id' => 'required|integer|exists:riga_ordine,id',
        ]);
        $result = $this->carrelloService->eliminaRiga($request->riga_ordine_id, $request->has('elimina'));
        return response()->json([
            'success' => true,
            'message' => 'Riga eliminata',
            'data' => $result,
        ]);
        // $riga = RigaOrdine::find($request->riga_ordine_id);
        // if($riga !== null && $request->has('elimina')){
        // $riga->delete();
        // };

        // return response()->json([
        //     'success' => true,
        //     'message' => 'Riga eliminata',
        //     'data' => $riga,
        // ]);
    }


    public function aggiorna_nota(Request $request){
        $request->validate([
            'riga_ordine_id' => 'required|integer|exists:riga_ordine,id',
            'note' => 'nullable|string',
        ]);
        $result = $this->carrelloService->aggiornaNota($request->riga_ordine_id, $request->note);
        return response()->json([
            'success' => true,
            'message' => 'Nota aggiornata',
            'data' => $result,
        ]);
        // $riga = RigaOrdine::find($request->riga_ordine_id);
        // if($riga == null){
        //     return response()->json([
        //         'success' => false,
        //         'message' => 'Riga ordine non trovata',
        //         'data' => null,
        //     ]);
        // }
        // $riga->note = $request->note;
        // $riga->save();
        // return response()->json([
        //     'success' => true,
        //     'message' => 'Nota aggiornata',
        //     'data' => $riga,
        // ]);
    }

    public function aggiungi_variante(Request $request){
        $request->validate([
            'tipo' => 'required|string|in:singolo,tutti',
            'piatto_id' => 'required|integer|exists:piatto,id',
            'riga_ordine_id' => 'required|integer|exists:riga_ordine,id',
            'variante_id' => 'nullable|integer|exists:variante_piatto,id',
            'nota' => 'nullable|string',
        ]);
        // dd($request->all());
        $request->nota = null;
        $result = null;
        if($request->tipo == 'singolo'){
            $result = $this->carrelloService->aggiungiVarianteSingoloPiatto($request->piatto_id, $request->riga_ordine_id, $request->variante_id, $request->nota);
            
        }elseif($request->tipo == 'tutti'){
            $result = $this->carrelloService->aggiungiVarianteTuttiPiatto($request->piatto_id, $request->riga_ordine_id, $request->variante_id, $request->nota);
        }else{

            return response()->json([
                'success' => false,
                'message' => 'Tipo di variante non valido.',
                'data' => null,
            ]);
        };

        return $result;
    }

    public function elimina_variante(Request $request){
        $request->validate([
            'riga_ordine_id' => 'required|integer|exists:riga_ordine,id',
            'variante_id' => 'required|integer|exists:variante_piatto,id',
        ]);
        $result = $this->carrelloService->eliminaVariante($request->riga_ordine_id, $request->variante_id);
        return response()->json($result);
    }   

    public function azzera(Request $request){
        $request->validate([
            'ordine_id' => 'required|integer|exists:ordine,id',
        ]);
        $result = $this->carrelloService->azzeraCarrello($request->ordine_id);
        return response()->json([
            'success' => $result['success'],
            'message' => $result['message'],
            'data' => $result['data'],
        ]);
        // $ordine = Ordine::find($request->ordine_id);
        // if($ordine == null){
        //     return response()->json([
        //         'success' => false,
        //         'message' => 'Ordine non trovato',
        //         'data' => null,
        //     ]);
        // }
        // $righe = RigaOrdine::where('ordine_id', $ordine->id)->delete();
        // $ordine->prezzo = 0;
        // $ordine->save();
        // $ordine->delete();

        // return response()->json([
        //     'success' => true,
        //     'message' => 'Carrello svuotato',
        //     'data' => null,
        // ]);
        // // switch(Dispositivo::cassa()->first()->tipo){
        // //     case Dispositivo::CASSA:
        // //         return redirect()->route('punto-vendita.show');
        // //         break;
        // //     case Dispositivo::TIPO_KIOSK:
        // //         // return redirect()->route('punto_vendita.kiosk.index');
        // //         return redirect()->route('punto-vendita.show');

        // //         break;
        // //     case Dispositivo::CAMERIERE:
        // //         // return redirect()->route('punto_vendita.cameriere.index');
        // //         return redirect()->route('punto-vendita.show');
                
        // //         break;
        // // }
    }

    public function totale(Request $request){
        $ordine = Ordine::find($request->ordine_id);
        if ($ordine == null){ 
            return response()->json([
                'success' => true,
                'message' => 'Totale carrello',
                'data' => 0,
                'totale' => 0,
                'quantita_totale' => 0,
            ]);
        }
        // dd([$ordine->prezzo , $request->all()]);
        if($ordine->prezzo == null || $ordine->prezzo == 0){
            if($ordine->righe_ordine->count() >0){
                $totale = $ordine->righe_ordine->sum('prezzo');
            }else{
                $totale = 0;
            }
        }else{
            $totale = $ordine->righe_ordine->sum('prezzo');
        }

        $quantitaTotale = (int) $ordine->righe_ordine->sum('quantita');

        return response()->json([
            'success' => true,
            'message' => 'Totale carrello',
            'data' => $totale,
            'totale' => $totale,
            'quantita_totale' => $quantitaTotale,
        ]);
    }
    public function aggiorna_info(Request $request){
        $ordine = Ordine::find($request->ordine_id);
        if($ordine == null){
            return response()->json([
                'success' => false,
                'message' => 'Ordine non trovato',
                'data' => null,
            ]);
        }
        $info = is_array($ordine->info) ? $ordine->info : [];
        $info['cliente'] = $request->cliente;
        $info['tavolo'] = $request->tavolo;
        $info['coperti'] = $request->filled('coperti') ? (int) $request->coperti : null;
        $ordine->info = $info;
        $ordine->save();
        return response()->json([
            'success' => true,  
            'message' => 'Info aggiornata',
            'data' => $ordine->info,
        ]);
    }


    public function checkout(Request $request){
        // $ordineA = Ordine::where([
        //     'stato' => Ordine::CARRELLO, 
        //     // 'dispositivo_id' => Session::get('dispositivo_id') || $request->dispositivo_id,
        //     'attivita_id' => Session::get('attivita_id') || $request->attivita_id,
        // ])->orderBy('created_at', 'desc')->first();
        $ordine = Ordine::find($request->ordine_id);
        if($ordine == null){
            return  response()->json([
                'success' => false,
                'message' => 'Ordine non trovato',
                'data' => null,
                'ordineA' => $ordineA,
                'ordineB' => $ordineB,
                // 'ordineA->id == ordineB->id' => $ordineA->id == $ordineB->id,
            ]);
        }

        $ordine->prezzo = $ordine->righe_ordine->sum('prezzo');
        // $ordine->stato = Ordine::CHECKOUT;
        $ordine->metodo_pagamento_id = $request->metodo_pagamento_id;
        $ordine->tipo = $request->tipo;
        $ordine->save();
        
    return view('punto_vendita.cassa._partials.carrello.pagamento.checkout', ['ordine' => $ordine, 'dispositivo' => $ordine->dispositivo, 'attivita' => $ordine->attivita]);
    }

    public function paga_ordine(Request $request){

        if(!$request->filled('tag_id') && MetodoPagamento::find($request->metodo_pagamento_id)->tipo == MetodoPagamento::SEGRESTA_WALLET){
            return back()->with('error', 'Tag ID obbligatorio per il metodo di pagamento Segresta Wallet');
        }
        
        $ordine = Ordine::find($request->ordine_id);
        if($ordine == null){
            return response()->json([
                'success' => false,
                'message' => 'Ordine non trovato',
                'data' => null,
            ]);
        }
        $pagamento = Pagamento::create([
            'attivita_id' => session('attivita_id'), //$request->attivita_id,
            'dispositivo_id' => $request->dispositivo_id,
            'ordine_id' => $ordine->id,
            'metodo_pagamento_id' => $request->metodo_pagamento_id,
            'tipo' => $request->tipo,
            'importo' => $ordine->prezzo,
            'causale' => $ordine->attivita->nome.' - Pagamento ordine #'.$ordine->id,
        ]);
        $ordine->pagamento_id = $pagamento->id;
        $ordine->stato = Ordine::IN_ATTESA_PAGAMENTO;
        $ordine->save();
        
        switch($pagamento->metodo_pagamento->tipo){
            case MetodoPagamento::CONTANTI:
                // $pagamento->stato = Pagamento::PAGATO;
                // $pagamento->save();
                // $ordine->update(['stato' => Ordine::PAGATO]);
                // return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con contanti riuscito. ->'.$pagamento->metodo_pagamento->tipo);
                
                $pagamentoResult = app('\App\Services\Paga\Contanti')->paga($pagamento);
                
                if($pagamentoResult['result'] === true){
                    $ordine->update(['stato' => Ordine::PAGATO]);
                    return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con contanti riuscito. ->'.$pagamento->metodo_pagamento->tipo);
                }else{
                    $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'Pagamento con contanti non riuscito. '.$pagamentoResult['message']);
                }

                break;
            case MetodoPagamento::BONIFICO:
                // $pagamento->update(['stato' , Pagamento::PAGATO]);
                // $pagamento->save();
                // return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con bonifico riuscito.');
                
                $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'METODO PAGAMENTO NON DISPONIBILE. ');

                break;  
            case MetodoPagamento::PAYPAL:
                // $pagamento->update(['stato' , Pagamento::PAGATO]);
                // $pagamento->save();
                // return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con paypal riuscito.');
                
                $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'METODO PAGAMENTO NON DISPONIBILE. ');

                break;
            case MetodoPagamento::CARTA_DI_DEBITO:  
                // $pagamento->update(['stato' , Pagamento::PAGATO]);
                // $pagamento->save();
                // return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con carta di debito riuscito.');
                
                $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'METODO PAGAMENTO NON DISPONIBILE. ');

                break;
            case MetodoPagamento::CUPON:
                $pagamentoResult = app('\App\Services\Paga\Cupon')->paga($pagamento);
                
                if($pagamentoResult['result'] === true){
                    $ordine->update(['stato' => Ordine::PAGATO]);
                    return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con cupon riuscito.');
                }else{
                    $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'Pagamento con cupon non riuscito. '.$pagamentoResult['message']);
                }
                break;
            case MetodoPagamento::SEGRESTA_WALLET:
                $pagamentoResult = app('\App\Services\Paga\SegrestaWallet')
                ->registraMovimento($pagamento, 'uscita', $ordine->prezzo, $ordine->attivita->nome.' - Pagamento ordine #'.$ordine->id, $request->tag_id);
                
                if($pagamentoResult['result'] === true){
                    $pagamento->update(['stato' => Pagamento::PAGATO]);
                    $pagamento->save();
                    return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con wallet riuscito.');
                }else{
                    $pagamento->stato = Pagamento::ERRORE;
                    $pagamento->save();
                    $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'Pagamento con wallet non riuscito. '.$pagamentoResult['message']);
                }
                break;
           
                case MetodoPagamento::APPLE_PAY:
                    // $pagamento->update(['stato' , Pagamento::PAGATO]);
                    // $pagamento->save();
                    // return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con apple pay riuscito.');
                    
                    $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'METODO PAGAMENTO NON DISPONIBILE. ');

                break;
            case MetodoPagamento::GOOGLE_PAY:
                // $pagamento->update(['stato' , Pagamento::PAGATO]);
                // $pagamento->save();
                // return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con google pay riuscito.');
                
                $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'METODO PAGAMENTO NON DISPONIBILE. ');

                break;
            case MetodoPagamento::POS:
                $pagamentoResult = app('\App\Services\Paga\Pos')->paga($pagamento);
                
                if($pagamentoResult['result'] === true){
                    $ordine->update(['stato' => Ordine::PAGATO]);
                    return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con contanti riuscito. ->'.$pagamento->metodo_pagamento->tipo);
                }else{
                    $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'Pagamento con contanti non riuscito. '.$pagamentoResult['message']);
                }

            case MetodoPagamento::STAFF:
                $pagamentoResult = app('\App\Services\Paga\Staff')->paga($pagamento);
                
                if($pagamentoResult['result'] === true){
                    $ordine->update(['stato' => Ordine::PAGATO]);
                    return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('success', 'Pagamento con staff riuscito.');
                }else{
                    $ordine->stato = Ordine::CARRELLO;
                    $ordine->save();
                    return back()->with('error', 'Pagamento con staff non riuscito. '.$pagamentoResult['message']);
                }
                break;
            default:
                $ordine->stato = Ordine::CARRELLO;
                $ordine->save();
                $pagamento->stato = Pagamento::ERRORE;
                $pagamento->save();
                return redirect()->route('punto-vendita.show', ['punto_vendita_id' => $ordine->dispositivo_id])->with('error', 'Metodo di pagamento non supportato. Pagamento non riuscito.'.$request->metodo_pagamento_id?? 'ND');
                break;
        }
    }
}
