<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
use App\Models\Endpoint;
use App\Models\Dispositivo;
use App\Models\PrintJob;
use App\DataTables\EndpointDataTable;
use Illuminate\Support\Facades\Validator;
use App\Models\Attivita;
use Illuminate\Support\Str;


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

    public function show(Request $request)
    {
        $endpoint = Endpoint::query()
            ->with(['attivita', 'user', 'licenza', 'stampanti'])
            ->find($request->endpoint_id);

        if (!$endpoint) {
            abort(404);
        }

        return view('endpoint.show', compact('endpoint'));
    }

    public function istruzioni(Request $request)
    {
        return view('endpoint.istruzioni', [
            'appUrl' => rtrim(config('app.url'), '/'),
        ]);
    }
    
    //API
    public function register(Request $request)
    {
        $request->validate([
            'label' => 'required|string|max:255',
            'descrizione' => 'required|string|max:255',
            'url' => 'nullable|string|max:255',
            'attivita_id' => 'required|integer|exists:attivita,id',
        ]);
        $endpoint = Endpoint::create([
            'label' => $request->label,
            'descrizione' => $request->descrizione,
            'url' => $request->url,
            'attivita_id' => $request->attivita_id,
            'user_id' => $request->user()->id,
            'info' => [
              'stampanti' => [],
            ],
        ]);
        return response()->json([
            'message' => 'Endpoint registrato con successo',
            'status' => 'success',
            'success' => true,
            'endpoint' => $endpoint
        ]);
    }

    public function stampanti_register(Request $request)
    {
        Log::info('stampanti_register');
        Log::info($request->all());

        $stampanti_da_registrare = $request->input('stampanti', []);
        $endpoint = $request->endpoint;
        $stampanti_endpoint = Dispositivo::where('endpoint_id', $request->endpoint->id)->where('tipo', Dispositivo::STAMPANTE)->get()->toArray();


        foreach($stampanti_da_registrare as $key => $stampante){

                Dispositivo::FirstOrCreate(
                    [
                        'url_stampante' => $stampante['url_stampante'],
                        'endpoint_id' => $request->endpoint->id
                    ],
                    
                    [
                        'nome' => $stampante['nome'],
                        'url_stampante' => $stampante['url_stampante'],
                        'endpoint_id' => $request->endpoint->id,
                        'tipo' => Dispositivo::STAMPANTE,
                        'attivita_id' => $request->endpoint->attivita_id,
                        'licenza' => null,
                        'ubicazione' => $endpoint->ubicazione,
                        'note' => null,
                        'is_attivo' => true,
                        'pin_sblocco' => null,
                    ]);
            // }
        }

        return response()->json([
            'message' => 'Stampanti registrate con successo',
            'status' => 'success',
            'success' => true,
            'stampanti' => $endpoint->fresh()->stampanti,
        ]);

    }

    public function get_lavoro(Request $request)
    {
        

        $has_lavoro = false;
        $endpoint = $request->endpoint;

        $stampanti = $endpoint->stampanti;
        $stampanti_ids = $endpoint->stampanti->pluck('id')->toArray();
        $query = PrintJob::whereIn('stampante_id', $stampanti_ids)
            ->where('stato', PrintJob::STATO_IN_CODA);

            $lavori = $query->get();
        if($query->count() > 0){
            PrintJob::whereIn('stampante_id', $stampanti_ids)
            ->where('stato', PrintJob::STATO_IN_CODA)
            ->update([
                'stato' => PrintJob::STATO_PRESO,
            ]);
            $has_lavoro = true;
        }else{
            $has_lavoro = false;
        }

        return response()->json([
            'message' => $has_lavoro ? 'Lavoro trovato con successo' : 'Nessun lavoro trovato',
            'status' => 'success',
            'success' => true,
            'lavoro' => $has_lavoro,
            'lavori' => $lavori,
        ]);

    }

    public function esito_stampa(Request $request)
    {
        $request->validate([
            'printJob_id' => 'required|integer|exists:print_job,id',
            'esito' => 'required|string|in:success,error',
            // 'endpoint_id' => 'required|integer|exists:endpoint,id',
        ]);

        $printJob = PrintJob::find($request->printJob_id)->where('stato', PrintJob::STATO_PRESO);
        if($printJob->count() == 0){
            return response()->json([
                'message' => 'Print job non trovato o non in stato preso',
                'status' => 'error',
                'success' => false,
            ]);
        };

        switch($request->esito){
            case 'success':
                $printJob->update([
                    'stato' => PrintJob::STATO_COMPLETATO,
                ]);
                break;
            case 'error':
                $printJob->update([
                    'stato' => PrintJob::STATO_FALLITO,
                ]);
                break;
        }
        return response()->json([
            'message' => 'Esito stampa aggiornato con successo',
        ]);
    }

    //WEB
    public function index(EndpointDataTable $dataTable)
    {
        return $dataTable->render('endpoint.index');
    }

    public function store(EndpointDataTableEditor $editor)
    {
        $request = request();
        $input = $request->all();
        if($request->has('action')){
            switch($input['action']){
                case 'create':
                    if(!Auth::user()->can('create-endpoint')) return;
                    break;  
                case 'edit':
                    if(!Auth::user()->can('edit-endpoint')) return;
                    break;
                case 'remove':
                    if(!Auth::user()->can('delete-endpoint')) return;
                    break;
            }
        }
        return $editor->process($request);
    }
    public function index_api(Request $request)
    {
        $endpoints = Endpoint::all();
        return response()->json([
         'message' => 'Endpoint trovati con successo',
         'count' => $endpoints->count(),
         'status' => 'success', 
         'success' => true, 
         'endpoints' => $endpoints]);
    }


    public function api_register_product_key(Request $request)
    {

        if($request->has('first_time') && $request->first_time == true){
            //la prima registrazione
            Log::info('api_register_product_key');
            Log::info('FIRST TIME');
            Log::info('Request: ' . json_encode($request->all()));
        $validator = Validator::make($request->all(), [
            'product_key' => 'required|string|max:25,exists:endpoint,product_key',
        ], [
            'product_key.required' => 'Il product key è richiesto',
            'product_key.string' => 'Il product key deve essere una stringa',
            'product_key.max' => 'Il product key deve essere lungo al massimo 25 caratteri',
            'product_key.exists' => 'Il product key non è valido',
        ]);

        if($validator->fails()){
            Log::error('api_register_product_key');
            Log::error('Request: ' . $request->all());
            Log::error('Validator fails: ' . $validator->messages());
            return response()->json([
                'message' => $validator->messages(),
                'status' => 'error',
                'success' => false,
            ], 422);
        }

        $endpoint = Endpoint::where('product_key', $request->product_key)->first();

        if(!$endpoint){
            Log::error('Endpoint non trovato');
            return response()->json([
                'message' => 'Endpoint non trovato',
                'status' => 'error',
                'success' => false,
            ], 404);
        }elseif($endpoint->status == Endpoint::REGISTRATO){
            Log::error('Endpoint già registrato');
            return response()->json([
                'message' => 'Endpoint già registrato',
                'status' => 'error',
                'success' => false,
            ], 400);
        }

        //Verifica l'attività dell'endpoint
        $attivita = $endpoint->attivita;
        if(!$attivita){
            Log::error('Attività non trovata');
            return response()->json([
                'message' => 'Attività non trovata',
                'status' => 'error',
                'success' => false,
            ], 404);
        }

        //attivo l'endpoint
        $endpoint->update([
            'status' => Endpoint::REGISTRATO,
            "info" => [
                "machine_fingerprint" => $request->machine_fingerprint ?? null,
            ],
        ]);

        //Verifica la licenza dell'endpoint

        //
        return response()->json([
            'message' => 'Endpoint trovato con successo',
            'status' => 'success',
            'success' => true,
            'endpoint' => $endpoint,
            'licenza' => $licenza??null,
            'attivita' => $attivita??null,
        ]);

    }else{
        //se non è la prima registrazione può modificare gli attributi dell'endpoint
        Log::info('api_register_product_key');
        Log::info('NOT ft');
        Log::info('Request: ' . json_encode($request->all()));
        // dd($request->all() , 'NOT ft');

        $validator = Validator::make($request->all(), [
            'label' => 'required|string|max:255',
            'descrizione' => 'nullable|string|max:255',
            'ubicazione' => 'nullable|string|max:255',
        ], [
            'label.required' => 'Il label è richiesto',
            'label.string' => 'Il label deve essere una stringa',
            'label.max' => 'Il label deve essere lungo al massimo 25 caratteri',
            'descrizione.string' => 'La descrizione deve essere una stringa',
            'descrizione.max' => 'La descrizione deve essere lungo al massimo 255 caratteri',
            'ubicazione.string' => 'L\'ubicazione deve essere una stringa',
            'ubicazione.max' => 'L\'ubicazione deve essere lungo al massimo 255 caratteri',
        ]);

        if($validator->fails()){

            Log::error('Validator fails: ' . $validator->messages());
            return response()->json([
                'message' => $validator->messages(),
                'status' => 'error',
                'success' => false,
            ], 422);
        }

        $endpoint = Endpoint::where('product_key', $request->product_key)->where('status', Endpoint::REGISTRATO)->first();
        if(!$endpoint){
            Log::error('Endpoint non trovato');
            Log::error('Request: ' . json_encode($request->all()));
            return response()->json([
                'message' => 'Endpoint non trovato',
                'status' => 'error',
                'success' => false,
            ], 404);
        }
        
        $endpoint->update([
            'label' => $request->label,
            'descrizione' => $request->descrizione,
            'ubicazione' => $request->ubicazione,
            'status' => Endpoint::ATTIVO,
            'token' => Str::random(32),
        ]);
        
        return response()->json([
            'message' => 'Endpoint aggiornato con successo',
            'status' => 'success',
            'success' => true,
            'endpoint' => $endpoint,
            'token' => $endpoint->token,
        ]);

    } //chiude else

    }

    public function richiedi_nuovo_product_key(Request $request)
    {
        $request->validate([
            'attivita_id' => 'required|integer|exists:attivita,id',
        ],[
            'attivita_id.required' => 'L\'attività è richiesta',
            'attivita_id.exists' => 'L\'attività non è valida',
        ]);


        $attivita = Attivita::find($request->attivita_id);
        
        $endpoint = Endpoint::FirstOrCreate(['attivita_id' => $attivita->id , 'status' => Endpoint::NON_REGISTRATO], [
            'attivita_id' => $attivita->id,
            'label' => 'non assegnato',
            'descrizione' => 'non assegnato',
            'url' => 'non assegnato',
            'user_id' => $request->user()->id,
            'status' => Endpoint::NON_REGISTRATO,
            'product_key' => 'FEST-'.strtoupper(Str::random(20)),
            'info' => [
                'stampanti' => [],
            ],
        ]);

        return view('endpoint.nuovo_product_key', [
            'success' => true,
            'endpoint' => $endpoint,
        ]);


    
    }
}
