<?php
namespace Clevercherry\Backslash4\Controllers\Admin;

use App\Models\Block;
use App\Models\MediaManager;
use Illuminate\Http\Request;
use Clevercherry\Backslash4\Controllers\Controller;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\View;
use App\Models\Dashboard;
use App\Models\Setting;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Str;
use Clevercherry\Backslash4\Backslash4;
use Clevercherry\Backslash4\Traits\apiTraitv1;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class DashboardController extends BkAdminController
{
    // public $adminView = 'backslash4::admin';  // uses generic
    public $adminRoute = 'admin.admins';
    public $AppModel = User::class;

    use apiTraitv1;

    /**
     * Returns the index page view
     * @return type
     */
    public function dashboard()
    {
        return view('backslash4::admin.dashboard')
            ->with('widgets', $this->getAllWidgets())
            ->with('widgetSections', $this->getWidgetSections())
            ->with('dashboardStatistics', $this->getDashboardStatistics());
    }

    public function getAllWidgets() : Array
    {
        $widgets=[];
        //$config = Config::get('backslash4');
        //$config = Backslash4::getDashboardConfig(); //either backslash4 or the tenent's version
        $cmsMenu = Backslash4:: getDashboardFlatCMS(); //tenant aware
        foreach($cmsMenu as $menu => $item)
        {
            $defaultorder =90000;
            if(empty(@$item['no-model']) && !isset($item['html'])) // ie. 'no-model' != 1 or not set, and not an html spacer
            {
                $n = '\\App\\Models\\'.Str::singular($menu);

                $moduleWidgets = $n::getDashboardWidgets();
                if(!empty($moduleWidgets))
                    foreach ( $moduleWidgets AS $w )
                        $widgets[] = $w;
            }           
        }

        //sort the widget if there is a widget-order field
        usort($widgets, function ($a, $b) 
                        { return (@$a['widget-order'] ?? 999999999) <=> (@$b['widget-order'] ?? 999999999); 
                        });

        return $widgets;
    }


    /**
     * 
     */

    public function getWidgetSections() : Array
    {
        $widgetSections = [];

        $widgetSections = [
            // [
            //     'name' => 'analytics',
            //     'title' => 'Analytics',
            //     'text' => 'Lorem ipsum',
            //     'section-order' => 1
            // ],
            // [
            //     'name' => 'create',
            //     'title' => 'Create',
            //     'text' => 'Lorem ipsum',
            //     'section-order' => 2
            // ]
        ];

        usort($widgetSections, function ($a, $b) 
        { 
            return (@$a['section-order'] ?? 999999999) <=> (@$b['section-order'] ?? 999999999); 
        });

        return $widgetSections;
    }

    public function getDashboardStatistics() : String
    {
        return '';
    }

    public function getEditBlock($slug)
    {
        if (class_exists(\Debugbar::class) && \Debugbar::isEnabled()) {
           \Debugbar::disable();
        }
        
        $block = new Block();
        $block->type = $slug;
        $block->active = true;

        return view('backslash4::components.bs-blocks.blockeditor-row')
                ->with('block', $block);
    }


    public function downloadFileFromPath(Request $request)
    {
        $fullpath = MediaManager::getStoragePath($request->file_path);
        if(Str::startsWith($request->file_path, 's3:'))
        {
            if(Storage::drive('s3')->exists($fullpath)){
                return Storage::drive('s3')->response($fullpath);
            }
        } else {
            if(File::exists($fullpath)) {
                return Storage::response($fullpath);
            }
        }

        return response(['error' => 'File not found, '.$request->file_path."\n ".$fullpath], 404);
    }

    public function getGoogleLatLng(Request $request)
    {
        $apiKey = Setting::getSetting('google-maps-api-key', 'AIzaSyD_OJKX-xyPSOaTCBLDZFRs9aI4drBTOtM');// 'AIzaSyAOsDrtcuXqC_CQDp3ZYNDcSiQD_wobTIs');

        return Backslash4::getGoogleLatLng($request->address, $apiKey, false);
    }

    // API Controller Functions ----------------------------------------------
    /**
     * send a network message to cchub based on the $request data
     * 
     * @param Request $request request data
     * 
     * @return View   a View response of JSON data
     */
    public function networkEvent(Request $request)
    {
        $resp = self::sendNetworkEvent(
            @$request->event,
            @$request->type,
            @$request->subtype,
            @$request->data
        );

        return response()->json(['status' => $resp ? 'ok' : 'error']);
    }

    /** 
     * Send a Network message to cchub containing the params
     * 
     * @param String $event the name of the network event
     * @param String $data  data for the event, most likely json_encoded
     * 
     * @return bool  success or fail, if no setting just returns true blindly
     */
    public static function sendNetworkEvent($event, $type, $subtype, $data) : bool
    {
        // send this data back to the API at cchub (default)
        $key = config('backslash4.api.v1.network_api_key', null);
        if (empty($key)) {
            $key = Setting::getSetting('bs4_network_api_key', null);
            if (empty($key)) {
                Log::info('no network key');
                return true;
            }
        }

        $secret = config('backslash4.api.v1.network_api_secret', null);
        if (empty($secret)) {
            $secret = Setting::getSetting('bs4_network_api_secret', null);
            if (empty($secret)) {
                Log::info('no secret');
                return true;
            }
        }

        Log::info('sending network', [$event, $type, $subtype, $data]);

        $destination = config('backslash4.api.v1.network_api_host_url', null);
        if (empty($destination)) {
            $destination = Setting::getSetting('bs4_network_api_host_url', null);

            if (empty($destination)) {
                if (Str::contains(request()->getHost(), '.local')) {
                    $destination = 'cchub.local/api/v1/network-event';
                } else {
                    $destination = 'cchub.clevercherry.com/api/v1/network-event';
                }
            }
        }

        $payload = [
            'hostname' => request()->getHost(),
            'event' => $event,
            'type' => $type,
            'subtype' => $subtype,
            'data' => $data,
            'key' => $key,
            'secret' => $secret,
        ];

        $response = null;
        try {
            Log::info('starting curl', [
                'destination' => $destination,
                'payload' => $payload
            ]);

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://' . $destination);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            // Set SSL options - adjust as needed for your environment
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

            $response = curl_exec($ch);

            if ($response === false) {
                $curlError = curl_error($ch);
                Log::error('cURL error: ' . $curlError, [
                    'destination' => $destination,
                    'payload' => $payload
                ]);
                curl_close($ch);
                return false;
            }

            curl_close($ch);

            Log::info('ending curl', [
                'response' => $response
            ]);
            
            return true;
        } catch (\Throwable $th) {
            //throw $th;
            Log::info('Network Event Curl',
                [   'error_msg' => $th->getMessage(),
                    'error' => $th,
                    'destination' => $destination,
                    'payload'=>@$payload,
                    'response' => @$response,
                ]);

            return false;
        }
    }

    /** 
	 * return an API response
	 * @param Request $request
	 * @param string $slug      a slug that represents part of the request/response
	 * 
	 * you WILL want to override this function in your own code
	 */
	public function apiV1(Request $request, $slug)
    {
        // does nothing yet and you should be overriding this in your own code
    }

}
