<?php

namespace Fir\Controllers;

use Fir\Views;

/**
 * The base Controller upon which all the other controllers are extended on
 */
class Controller
{
    /**
     * The database connection
     * @var    object
     */
    public object $db;

    /**
     * The site settings from the DB
     * @var    array
     */
    protected array $settings;

    /**
     * The view object to be passed to the controllers
     * @var object
     */
    protected object $view;

    /**
     * The current URL path (route) arrays to be passed to the controllers
     * @var array
     */
    protected array $url;
    private array $extensions;
    private array $whatsapp;

    /**
     * Controller constructor.
     * @param $db
     * @param $url
     */
    public function __construct($db, $url)
    {
        $this->db = $db;
        $this->url = $url;

        // Set the site settings and extensions
        $settings = $this->model('Settings');
        $this->settings = $settings->get();
        $this->extensions = $settings->livechat();
        $this->whatsapp = $settings->whatsapp();

        // Set the timezone
        if (!empty($this->settings['timezone'])) {
            date_default_timezone_set($this->settings['timezone']);
        }

        // Instantiate the View
        $this->view = new Views\View($this->settings, $this->extensions, $this->whatsapp, $this->url);
    }

    /**
     * Get and instantiate the requested model
     * @param   $model  string  The model to instantiate
     * @return  object
     */
    public function model(string $model): object
    {
        require_once(__DIR__ . '/../models/' . $model . '.php');

        // The namespace\class must be defined in a string as it can't be called shorted using new namespace\$var
        $class = 'Fir\Models\\' . $model;

        return new $class($this->db);
    }

    /**
     * Get and instantiate the requested library
     * @param   $library  string  The library to instantiate
     * @return  object
     */
    public function library(string $library): object
    {
        require_once(__DIR__ . '/../libraries/' . $library . '.php');

        // The namespace\class must be defined in a string as it can't be called shorted using new namespace\$var
        $class = 'Fir\Libraries\\' . $library;

        return new $class($this->db);
    }

    /**
     * Output the final view to the user based on the request type
     *
     * @param   $data   array|null   The output generated by the controllers
     */
    public function run(array $data = null): void
    {
        if(empty($this->url[0])) {
            $this->url[0] = 'home';
        }   
        
        if($this->url[0] == 'admin') {
            $data['url'] = $this->url[1];
            if($this->url[1] == 'login'):
                $data['content_view'] = $data['content'];
            else:
                $data['navigation_view'] = $this->getAdminNavigation();
                $data['sidenav_view'] = $this->getAdminSidenav();
                $data['content_view'] = $data['content'];
                $data['footer_view'] = $this->getAdminFooter();
            endif;
            $data['scripts_view'] = $this->getAdminScripts();
            echo $this->view->render($data, 'wrapper-admin');
        }else {
            $data['url'] = $this->url[0];
            if ($this->url[0] == 'user') {
                $data['header_view'] = $this->getHeader();
                
                if ($this->url[0] == 'user') {
                    $data['navigation_view'] = $this->getUserNavigation();
                    $data['sidenav_view'] = $this->getUserSidenav();
                    $data['scripts_view'] = $this->getUserScripts();
                }
                
                $data['content_view'] = $data['content'];
                $data['footer_view'] = $this->getFooter();
            } else {
                $data['url_two'] = isset($this->url[1]);
                $data['header_view'] = $this->getHeader();
                $data['content_view'] = $data['content'];
                $data['footer_view'] = $this->getFooter();
                $data['scripts_view'] = $this->getHomeScripts();
            }

            if (in_array($this->url[0], ['cron', 'initiated'])) {
                echo $this->view->render($data, 'wrapper-cron');

            }elseif (in_array($this->url[0], ['login', 'register', 'forgot', 'reset', 'setup', 'google', 'meta', 'twofa'])) {
                echo $this->view->render($data, 'wrapper-auth');

            }elseif (in_array($this->url[0], ['blocked', 'maintenance'])) {
                echo $this->view->render($data, 'wrapper-blocked');

            }elseif (in_array($this->url[0], ['payment', 'investment', 'payout'])) {
                echo $this->view->render($data, 'wrapper-payment');

            }elseif ($this->url[0] == 'coins') {
                echo $this->view->render($data, 'wrapper-coins');
                
            }elseif ($this->url[0] == 'user') {
                echo $this->view->render($data, 'wrapper-user');
                
            }else {
                echo $this->view->render($data, 'wrapper');
            }
        }
    }

    /**
     * This is the method from where you can pass data to the Header view
     *
     * @return string
     */
    private function getHeader(): string
    {

        $data['url'] = $this->url[0];
        
        /*Use User Library*/
        $user = $this->library('User');
        $data['user'] = $user->data();
        $data['user_isloggedin'] = $user->isLoggedIn();

        /* Use User Model */
        $userModel = $this->model('User');

        // services
        $data['services'] = $userModel->services();
        // get the referral settings
        $data['referral-settings'] = $userModel->referralSettings();

        return $this->view->render($data, 'shared/header');
    }

    /**
     * This is the method from where you can pass data to the Footer view
     *
     * @return string
     */
    private function getFooter(): string
    {
        $data = [];
        return $this->view->render($data, 'shared/footer');
    }

    /**
     * This is the method from where you can pass data to the Scripts View
     *
     * @return string
     */
    private function getHomeScripts(): string
    {
        $data = [];

        /* Use User Model */
        $user = $this->library('User');
        $data['user'] = $user->data();

        return $this->view->render($data, 'home/template/scripts');
    } 

    /**
     * This is the method from where you can pass data to the Footer view
     *
     * @return string
     */
    private function getUserSidenav(): string
    {
        $data = [];
        $data['url'] = $this->url[1];
        
        /*Use User Library*/
        $user = $this->library('User');
        $data['user'] = $user->data();

        /* Use Settings Model */
        $settingsModel = $this->model('Settings');
        $data['settings'] = $settingsModel->get();

        return $this->view->render($data, 'user/template/sidenav');
    }

    /**
     * This is the method from where you can pass data to the Header view
     *
     * @return string
     */
    private function getUserNavigation(): string
    {
        $data = [];
        $data['url'] = $this->url[1];
        
        /*Use User Library*/
        $user = $this->library('User');
        $data['user'] = $user->data();

        /* Use Settings Model */
        $settingsModel = $this->model('Settings');
        $data['settings'] = $settingsModel->get();

        return $this->view->render($data, 'user/template/navigation');
    }

    /**
     * This is the method from where you can pass data to the Scripts View
     *
     * @return string
     */
    private function getUserScripts(): string
    {
        /**
         * The $data array stores all the data passed to the views
         */
        $data = [];
        
        /*Use User Library*/
        $user = $this->library('User');
        $data['user'] = $user->data();
        $data['user_isloggedin'] = $user->isLoggedIn();

        /* Use User Model */
        $userModel = $this->model('User');

        /* Use Settings Model */
        $settingsModel = $this->model('Settings');

        // retrieve the gateways 
        $data['gateways'] = $settingsModel->getGateways();
        $data['withdrawal-gateways'] = $settingsModel->getWithdraws(); 

        // Retrieve plans
        $data['plans'] = $userModel->plans();

        return $this->view->render($data, 'user/template/scripts');
    }

    /**
     * This is the method from where you can pass data to the Header view
     *
     * @return string
     */
    private function getAdminNavigation(): string
    {
        
        $data['url'] = $this->url[1];
        
        /*Use Admin Library*/
        $admin = $this->library('Admin');
        $data['admin'] = $admin->data();

        return $this->view->render($data, 'admin/template/navigation');
    }

    /**
     * This is the method from where you can pass data to the Footer view
     *
     * @return string
     */
    private function getAdminSidenav(): string
    {
        $data['url'] = $this->url[1];
        $admin = $this->library('Admin');
        $data['admin'] = $admin->data();

        $adminModel = $this->model('Admin');
        $investmentModel = $this->model('Investments');
        
        $data['banned-users-count'] = $adminModel->BannedUsersCount();
        $data['kyc-unverified-count'] = $adminModel->KYCUnverifiedCount();
        $data['kyc-pending-count'] = $adminModel->KYCPendingCount();
        $data['running-investments-count'] = $investmentModel->CountRunningInvestments();
        $data['pending-withdrawals-count'] = $adminModel->CountPendingWithdrawals();
        $data['initiated-withdrawals-count'] = $adminModel->CountInitiatedWithdrawals();
        $data['initiated-deposits-count'] = $adminModel->CountInitiatedDeposits();
        $data['pending-deposits-count'] = $adminModel->CountPendingDeposits();
        
        return $this->view->render($data, 'admin/template/sidenav');
    }

    /**
     * This is the method from where you can pass data to the Footer view
     *
     * @return string
     */
    private function getAdminFooter(): string
    {
        $data = [];
        return $this->view->render($data, 'admin/template/footer');
    }

    /**
     * This is the method from where you can pass data to the Scripts View
     *
     * @return string
     */
    private function getAdminScripts(): string
    {
        $data['url'] = $this->url[1];
        /* Use Admin Library */
        $admin = $this->library('Admin');
        $data['admin'] = $admin->data();

        /* Use Settings Model */
        $settingsModel = $this->model('Settings');
        $data['settings'] = $settingsModel->get();

        $adminModel = $this->model('Admin');

        $data['gateways'] = $settingsModel->getGateways(); 
        $data['withdrawal-gateways'] = $settingsModel->getWithdraws();
        $data['plans'] = $adminModel->plans();
        $data['users'] = $adminModel->Users();

        return $this->view->render($data, 'admin/template/scripts');
    }
}