<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Closure;
use Illuminate\Support\Facades\Log;

use Illuminate\Validation\Rule;


/**
 * This instance should not be modified or altered except if extending Creatia.
 * It merely exists as a means to provide extra functionality to applications.
 */
class BaseController extends Controller
{
    use AuthorizesRequests;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('api');
    }

    public function forbidden_resource_nyi() {
        return response()->json(['detail' => 'Forbidden: Alpha Rights Required'], 403);
    }

    public function pagination_table_request(Request $_r, Closure $_fn, Closure $_search = null, Closure $_sorting = null, Closure $_transform = null, $valid_order_keys = []) {
        $validated = $_r->validate([
            'draw' => 'integer',
            'start' => 'required|min:0',
            'length' => 'required|min:0',
            'order_direction' => Rule::in(['asc', 'desc']),
            'order_column' => Rule::in($valid_order_keys)
        ]);

        try {
            if($validated) {
                // Retrieve our unexecuted, simplest query.
                $query = $_fn();

                // Apply search over the function
                if($_search != null) {
                    $search_data = json_decode(urldecode($_r->input('search')), true);

                    $_query = $_search($query, $search_data['global'] ?? null, $search_data['filters'] ?? null);
                }

                // Apply ordering function over the prefix
                if($_sorting != null) {
                    $query = $_sorting($query, $_r->order_column, $_r->order_direction);
                }

                Log::debug($query->toSql());

                $filter_count = $query->count();
                $data = $_r->length == 0 ? $query->get() : $query->skip($_r->start)->take($_r->length)->get();
                $total_count = $data->count();

                if($_transform != null) {
                    $data = $_transform($data);
                }
    
                return response()->json([
                    'draw' => intval($_r->draw) ?? 0,
                    'recordsTotal' => $total_count,
                    'recordsFiltered' => $filter_count,
                    'data' => $data
                ], 200);
            }    
        } catch(Exception $ex) {}

        return response()->json(['detail' => 'Error processing the request'], 500);
    }

    public function pagination_api_request(Request $_r, Closure $_fn, $valid_order_keys = []) {
        $validated = $_r->validate([
            'draw' => 'integer',
            'start' => 'required|min:0',
            'length' => 'required|min:0',
            'order_direction' => Rule::in(['asc', 'desc']),
            'order_column' => Rule::in($valid_order_keys)
        ]);

        try {
            if($validated) {
                $result = $_fn($_r->draw, $_r->start, $_r->length, $_r->order_direction, $_r->order_column);
    
                return response()->json([
                    'draw' => intval($result['draw']) ?? 0,
                    'recordsTotal' => $result['total'],
                    'recordsFiltered' => $result['filtered'],
                    'data' => $result['data']
                ], 200);
            }    
        } catch(Exception $ex) {}

        return response()->json(['detail' => 'Error processing the request'], 500);
    }

}
