<?php

namespace App\Modules\Latency\Controllers;

// Laravel and vendor inclusions.
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

// Creatia inclusions.
use App\Http\Controllers\BaseController;
use App\Models\User;

// Custom module inclusions.
use App\Modules\Latency\Models\DynamicLatencies;
use App\Modules\Latency\Models\StaticLatencies;
use App\Modules\Latency\Models\LatencyLocations;

class AdminController extends BaseController
{
    public function get_locations(Request $_r) {
        return BaseController::pagination_api_request($_r, function($draw, $start, $length) {
            $data = LatencyLocations::select('id', 'name');

            if($start !== '0' && $length !== '0') {
                $data = $data->skip($start)->take($length);
            }
            
            $data = $data->get();

            $count = $data->count();

            return [
                'draw' => $draw,
                'total' => $count,
                'filtered' => $count,
                'data' => $data,
            ];
        });
    }

    public function get_location_static_latency(Request $_r, $location_id) {
       
        if(!LatencyLocations::find($location_id)) {
            return response()->json(['detail' => 'Error processing the request'], 500);
        }

        $data = StaticLatencies::select('location_b', 'latency')->where('location_a', '=', $location_id)->get();

        return response()->json($data, 200);
    }

    public function get_static_latencies(Request $_r) {
        return BaseController::pagination_api_request($_r, function($draw, $start, $length) {
            $data = StaticLatencies::select(DB::raw('location_a_table.id as location_a_id, location_b_table.id as location_b_id, latency'))
                ->leftJoin('latency_locations as location_a_table', 'location_a', '=', 'location_a_table.id')
                ->leftJoin('latency_locations as location_b_table', 'location_b', '=', 'location_b_table.id')
                ->skip($start)
                ->take($length)
                ->get();

            $count = $data->count();

            return [
                'draw' => $draw,
                'total' => $count,
                'filtered' => $count,
                'data' => $data,
            ];
        });
    }

    public function get_dynamic_latencies(Request $_r) {
        return BaseController::pagination_api_request($_r, function($draw, $start, $length) {
            $data = DynamicLatencies::select(DB::raw('location_a_table.name as location_a_name, location_b_table.name as location_b_name, latency'))
                ->leftJoin('latency_locations as location_a_table', 'location_a', '=', 'location_a_table.id')
                ->leftJoin('latency_locations as location_b_table', 'location_b', '=', 'location_b_table.id')
                ->skip($start)
                ->take($length)
                ->get();

            $count = $data->count();

            return [
                'draw' => $draw,
                'total' => $count,
                'filtered' => $count,
                'data' => $data,
            ];
        });
    }

    public function post_location(Request $_r) {
        $valid_request = $_r->validate([
            "name"  => "required|string"
        ]);

        $response = response()->json(['detail' => 'Error generating location.'], 500);

        if($valid_request) {
            $new_location = LatencyLocations::create(['name' => $_r->input('name')])->id;

            $response = response()->json(['id' => $new_location], 200);
        }

        return $response;
    }

    public function post_latencies(Request $_r, $location_id) {

        $valid_request = $_r->validate([
            "latency"               => "required|array",
            "latency.*.location_b"  => "required|integer",
            "latency.*.latency"     => "required|string",
        ]);

        $response = response()->json(['detail' => 'Error generating latencies'], 500);

        if($valid_request) {
            $rows = [];

            foreach($_r->input('latency') as $latency) {
                // Location A row update.
                $rows[] = ['location_a' => $location_id, 'location_b' => $latency['location_b'], 'latency' => $latency['latency']];

                // Location B row update.
                $rows[] = ['location_a' => $latency['location_b'], 'location_b' => $location_id, 'latency' => $latency['latency']];
            }

            StaticLatencies::upsert($rows, ['location_a', 'location_b'], ['latency']);

            $response = response()->json(['data' => 'Successfully updated latencies'], 200);
        }

        return $response;
    }    
}
