<?php
namespace App\Http\Controllers;

use App\Rules\IsMultiLang;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\LengthAwarePaginator as Paginator;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Input;
use Mail;
use Redirect;
use Validator;

abstract class Controller extends BaseController
{

    use DispatchesJobs, ValidatesRequests;

    protected $user_id;
    protected $users;

    public function __construct()
    {

        $this->middleware('ipblocked');
        $driver = config('database.default');
        $database = config('database.connections');

        $this->db = $database[$driver]['database'];
        $this->dbuser = $database[$driver]['username'];
        $this->dbpass = $database[$driver]['password'];
        $this->dbhost = $database[$driver]['host'];


        $website = config('website');
        $this->config = $website;
        $this->data['websiteConfig'] = $website;
    }


    function getAjaxselect(Request $request)
    {

        if ($request->ajax() == true && \Auth::check() == true) {

            $param = explode(':', $request->input('filter'));
            $parent = (!is_null($request->input('parent')) ? $request->input('parent') : null);
            $where = (!is_null($request->input('where')) ? $request->input('where') : null);
            $limit = (!is_null($request->input('limit')) ? $request->input('limit') : null);
            $values = (!is_null($request->input('values')) ? $request->input('values') : null);
            $search = (!is_null($request->input('search')) ? $request->input('search') : null);
            // if( strlen($values)<1 && strlen($search)<1 )
            // return (['items' => [], 'pagination' =>  false]);

            $rows = $this->model->getAjaxselect($param, $limit, $parent, $values, $where, $search);
            return (['items' => $rows->toArray()['data'], 'pagination' => $rows->nextPageUrl() ? true : false]);

        } else {
            return json_encode(array('OMG' => " Ops .. Cant access the page !"));
        }
    }

    function getComboselect(Request $request)
    {

        if ($request->ajax() == true && \Auth::check() == true) {
            $param = explode(':', $request->input('filter'));
            $parent = (!is_null($request->input('parent')) ? $request->input('parent') : null);
            $where = (!is_null($request->input('where')) ? $request->input('where') : null);
            $limit = (!is_null($request->input('limit')) ? $request->input('limit') : null);
            $values = (!is_null($request->input('values')) ? $request->input('values') : null);
            $rows = $this->model->getComboselect($param, $limit, $parent, $values, $where);
            $items = array();

            $fields = explode("|", $param[2]);

            foreach ($rows as $row) {
                $value = "";
                foreach ($fields as $item => $val) {
                    if ($val != "") {
                        $lval = json_decode($row->{$val});
                        if (isset($lval->{config('website.cnf_lang')}))
                            $value .= $lval->{config('website.cnf_lang')};
                        else
                            $value .= $row->{$val} . " ";
                    }


                }
                $items[] = array($row->{$param['1']}, $value);

            }

            return json_encode($items);
        } else {
            return json_encode(array('OMG' => " Ops .. Cant access the page !"));
        }
    }

    public function getCombotable(Request $request)
    {
        if (Request::ajax() == true && Auth::check() == true) {
            $rows = $this->model->getTableList($this->db);
            $items = array();
            foreach ($rows as $row)
                $items[] = array($row, $row);
            return json_encode($items);
        } else {
            return json_encode(array('OMG' => "  Ops .. Cant access the page !"));
        }
    }

    public function getCombotablefield(Request $request)
    {
        if ($request->input('table') == '')
            return json_encode(array());
        if (Request::ajax() == true && Auth::check() == true) {


            $items = array();
            $table = $request->input('table');
            if ($table != '') {
                $rows = $this->model->getTableField($request->input('table'));
                foreach ($rows as $row)
                    $items[] = array($row, $row);
            }
            return json_encode($items);
        } else {
            return json_encode(array('OMG' => "  Ops .. Cant access the page !"));
        }
    }

    function postMultisearch(Request $request)
    {
        $post = $_POST;
        $items = '';
        foreach ($post as $item => $val):
            if ($_POST[$item] != '' and $item != '_token' and $item != 'md' && $item != 'id'):
                $items .= $item . ':' . trim($val) . '|';
            endif;

        endforeach;

        return Redirect::to($this->module . '?search=' . substr($items, 0, strlen($items) - 1) . '&md=' . $request->inpuy('md'));
    }

    function buildSearch($map = false)
    {

        $keywords = '';
        $fields = '';
        $param = '';
        $allowsearch = $this->info['config']['forms'];
        foreach ($allowsearch as $as)
            $arr[$as['field']] = $as;
        $mapping = '';
        if ($_GET['search'] != '') {
            $type = explode("|", $_GET['search']);
            if (count($type) >= 1) {
                foreach ($type as $t) {
                    $keys = explode(":", $t);
                    if (in_array($keys[0], array_keys($arr))):
                        if ($arr[$keys[0]]['type'] == 'select' || $arr[$keys[0]]['type'] == 'radio') {
                            $param .= " AND " . $arr[$keys[0]]['alias'] . "." . $keys[0] . " " . self::searchOperation($keys[1]) . " '" . $keys[2] . "' ";
                            $mapping .= $keys[0] . ' ' . self::searchOperation($keys[1]) . ' ' . $keys[2] . '<br />';

                        } else {
                            $operate = self::searchOperation($keys[1]);
                            if ($operate == 'like') {
                                $param .= " AND " . $arr[$keys[0]]['alias'] . "." . $keys[0] . " LIKE '%" . trim($keys[2]) . "%%' ";
                                $mapping .= $keys[0] . ' LIKE ' . $keys[2] . '<br />';
                            } else if ($operate == 'is_null') {
                                $param .= " AND " . $arr[$keys[0]]['alias'] . "." . $keys[0] . " IS NULL ";
                                $mapping .= $keys[0] . ' IS NULL <br />';

                            } else if ($operate == 'not_null') {
                                $param .= " AND " . $arr[$keys[0]]['alias'] . "." . $keys[0] . " IS NOT NULL ";
                                $mapping .= $keys[0] . ' IS NOT NULL <br />';

                            } else if ($operate == 'between') {
                                $param .= " AND (" . $arr[$keys[0]]['alias'] . "." . $keys[0] . " BETWEEN '" . $keys[2] . "' AND '" . $keys[3] . "' ) ";
                                $mapping .= $keys[0] . ' BETWEEN ' . $keys[2] . ' - ' . $keys[3] . '<br />';
                            } else {
                                $param .= " AND " . $arr[$keys[0]]['alias'] . "." . $keys[0] . " " . self::searchOperation($keys[1]) . " '" . $keys[2] . "' ";
                                $mapping .= $keys[0] . ' ' . self::searchOperation($keys[1]) . ' ' . $keys[2] . '<br />';
                            }
                        }
                    endif;
                }
            }

        }

        if ($map == true) {
            return $param = array(
                'param' => $param,
                'maps' => '
					<div class="infobox infobox-info fade in" style="font-size:10px;">
					  <button data-dismiss="alert" class="close" type="button"> x </button>
					 <b class="text-danger"> Search Result </b> :  <br /> ' . $mapping . '
					</div>
					'
            );

        } else {
            return $param;
        }


    }

    function buildSearchMessage($map = true)
    {

        $keywords = '';
        $fields = '';
        $param = [];
        $type = [];

        $mapping = '';
        if ($_GET['search'] != '') {
            $type = explode("|", trim(urldecode(str_replace('+', '%2B', $_GET['search'])), '|'));
            if (count($type) >= 1) {
                foreach ($type as $t) {
                    $keys = explode(":", $t);
                    if (count($keys) >= 3):
                        $operate = self::searchOperation($keys[1]);
                        if ($operate == 'like') {
                            $mapping .= $keys[0] . ' LIKE ' . trim($keys[2]) . '<br />';
                        } else if ($operate == 'is_null') {
                            $mapping .= $keys[0] . ' IS NULL <br />';

                        } else if ($operate == 'not_null') {
                            $mapping .= $keys[0] . ' IS NOT NULL <br />';

                        } else if ($operate == 'between') {
                            $mapping .= $keys[0] . ' BETWEEN ' . $keys[2] . ' - ' . $keys[3] . '<br />';
                        } else {
                            $mapping .= $keys[0] . ' ' . self::searchOperation($keys[1]) . ' ' . $keys[2] . '<br />';
                        }
                    endif;
                }
            }
        }

        if ($map == true) {
            return $param = array(
                'param' => $type,
                'maps' => '
					<div class="infobox infobox-info fade in" style="font-size:10px;">
					  <button data-dismiss="alert" class="close" type="button"> x </button>
					 <b class="text-danger"> Search Result </b> :  <br /> ' . $mapping . '
					</div>
					'
            );

        } else {
            return $param;
        }


    }

    function onSearch($params)
    {
        // Used for extracting URL GET search
        $psearch = explode('|', $params);
        $currentSearch = array();
        foreach ($psearch as $ps) {
            $tosearch = explode(':', $ps);
            if (count($tosearch) >= 2)
                $currentSearch[$tosearch[0]] = $tosearch[2];
        }
        return $currentSearch;
    }

    function searchOperation($operate)
    {
        $val = '';
        switch ($operate) {
            case 'equal':
                $val = '=';
                break;
            case 'not_equal':
                $val = '<>';
                break;
            case 'bigger_equal':
                $val = '>=';
                break;
            case 'smaller_equal':
                $val = '<=';
                break;
            case 'smaller':
                $val = '<';
                break;
            case 'bigger':
                $val = '>';
                break;
            case 'not_null':
                $val = 'not_null';
                break;

            case 'is_null':
                $val = 'is_null';
                break;

            case 'like':
                $val = 'like';
                break;

            case 'between':
                $val = 'between';
                break;

            default:
                $val = '=';
                break;
        }
        return $val;
    }

    function inputLogs(Request $request, $note = NULL)
    {
        $data = array(
            'module' => $request->segment(1),
            'task' => $request->segment(2),
            'user_id' => Session::get('uid'),
            'ipaddress' => $request->getClientIp(),
            'note' => $note
        );
        \DB::table('tb_logs')->insert($data);
        ;

    }

    function validateForm($forms = array())
    {
        if (count($forms) <= 0)
            $forms = $this->info['config']['forms'];

        $feild_rules = [];

        foreach ($forms as $form) {

            if ($form['required'] > 0 && $form['type'] != 'hidden') {
                $feild_rules[$form['field']][] = 'required';
            }

            if (isset($form['unique']) && $form['unique'] > 0) {
                $feild_rules[$form['field']][] = Rule::unique($this->info['table'], $form['field'])->ignore(request($this->info['key']));
            }

            (!isset($form['validations'])) ? $form['validations'] = '' : null;

            if ($form['validations'] != '' && $form['type'] == 'text')
                $feild_rules[$form['field']][] = str_replace(array('=', 'length'), array(':', ''), $form['validations']);


            if ($form['type'] == 'file') {
                if ($form['option']['upload_type'] == 'image') {
                    $feild_rules[$form['field']][] = 'mimes:jpg,jpeg,png,gif,bmp,svg,webp';

                } else {
                    $feild_rules[$form['field']][] = 'mimes:zip,csv,xls,doc,docx,xlsx,pdf,rtf';
                }
            } else if ($form['type'] == 'text_number')
                $feild_rules[$form['field']][] = 'integer';
            else if ($form['type'] == 'text_decimal')
                $feild_rules[$form['field']][] = 'numeric';
            else if ($form['type'] == 'lang')
                $feild_rules[$form['field']][] = new IsMultiLang;
            else if ($form['type'] == 'text_date')
                $feild_rules[$form['field']][] = 'date_format:Y-m-d';
            else if ($form['type'] == 'text_time')
                $feild_rules[$form['field']][] = 'date_format:Y-m-d H:i:s';
            else if ($form['type'] == 'radio') {
                $radio_values = [];
                $opt = explode("|", $form['option']['lookup_query']);
                for ($i = 0; $i < count($opt); $i++) {
                    $optar = explode(":", $opt[$i]);
                    $radio_values[] = trim($optar[0]);
                }
                if (count($radio_values) > 0)
                    $feild_rules[$form['field']][] = 'in:' . (implode(',', $radio_values));
            } else if ($form['type'] == 'checkbox') {
                $radio_values = [];
                $opt = explode("|", $form['option']['lookup_query']);
                for ($i = 0; $i < count($opt); $i++) {
                    $optar = explode(":", $opt[$i]);
                    $radio_values[] = trim($optar[0]);
                }
                if (count($radio_values) > 0)
                    $feild_rules[$form['field']][] = 'in:' . (implode(',', $radio_values));
            } else if ($form['type'] == 'select') {

                if (strlen($form['option']['lookup_query']) > 1) {
                    $radio_values = [];
                    $opt = explode("|", $form['option']['lookup_query']);
                    for ($i = 0; $i < count($opt); $i++) {
                        $optar = explode(":", $opt[$i]);
                        $radio_values[] = trim($optar[0]);
                    }
                    if (count($radio_values) > 0)
                        $feild_rules[$form['field']][] = 'in:' . (implode(',', $radio_values));
                } else if (strlen($form['option']['lookup_table']) > 1) {
                    if (!isset($form['required']) || !$form['required']) {
                        $feild_rules[$form['field']][] = 'nullable';
                    }
                    $feild_rules[$form['field']][] = 'exists:' . $form['option']['lookup_table'] . ',' . $form['option']['lookup_key'];
                }

            }

        }

        return $feild_rules;

    }

    function validateListError($rules)
    {
        $errMsg = __('core.note_error');
        $errMsg .= '<hr /> <ul>';
        foreach ($rules as $key => $val) {
            $errMsg .= '<li>' . $key . ' : ' . $val[0] . '</li>';
        }
        $errMsg .= '</li>';
        return $errMsg;
    }

    function validatePost($request)
    {
        $str = $this->info['config']['forms'];
        $data = array();
        foreach ($str as $f) {
            $field = $f['field'];
            // Update for V5.1.5 issue on Autofilled createOn and updatedOn fields
            if ($field == 'createdOn')
                $data['createdOn'] = date('Y-m-d H:i:s');
            if ($field == 'updatedOn')
                $data['updatedOn'] = date('Y-m-d H:i:s');
            if ($f['view'] == 1) {


                if ($f['type'] == 'textarea_editor' || $f['type'] == 'textarea') {
                    $data[$field] = $request->input($field);
                } else {

                    //					if(!is_null( $request->input( $field ) ))
                    $data[$field] = $request->input($field);

                    // if post is file or image


                    if ($f['type'] == 'file') {

                        if (!is_dir(public_path() . $f['option']['path_to_upload']))
                            mkdir(public_path() . $f['option']['path_to_upload'], 0777);

                        $files = '';
                        if ($f['option']['upload_type'] == 'file') {

                            if (isset($f['option']['image_multiple']) && $f['option']['image_multiple'] == 1) {
                                if (isset($_POST['curr' . $field])) {
                                    $curr = '';
                                    for ($i = 0; $i < count($_POST['curr' . $field]); $i++) {
                                        $files .= $_POST['curr' . $field][$i] . ',';
                                    }
                                }

                                if (!is_null($request->file($field))) {

                                    $destinationPath = '.' . $f['option']['path_to_upload'];
                                    foreach ($_FILES[$field]['tmp_name'] as $key => $tmp_name) {
                                        $file_name = $_FILES[$field]['name'][$key];
                                        $file_tmp = $_FILES[$field]['tmp_name'][$key];
                                        if ($file_name != '') {
                                            move_uploaded_file($file_tmp, $destinationPath . '/' . $file_name);
                                            $files .= $file_name . ',';

                                        }

                                    }

                                    if ($files != '')
                                        $files = substr($files, 0, strlen($files) - 1);
                                    $data[$field] = $files;
                                } else {
                                    unset($data[$field]);
                                }


                            } else {

                                if (!is_null($request->file($field))) {

                                    $file = $request->file($field);
                                    $destinationPath = '.' . $f['option']['path_to_upload'];
                                    $filename = $file->getClientOriginalName();
                                    $extension = $file->getClientOriginalExtension(); //if you need extension of the file
                                    $rand = rand(1000, 100000000);
                                    $newfilename = strtotime(date('Y-m-d H:i:s')) . '-' . $rand . '.' . $extension;
                                    $uploadSuccess = $file->move($destinationPath, $newfilename);
                                    if ($uploadSuccess) {
                                        $data[$field] = $newfilename;
                                    }
                                }
                            }

                        } else {

                            if (!is_dir(public_path() . $f['option']['path_to_upload']))
                                mkdir(public_path() . $f['option']['path_to_upload'], 0777);

                            if (isset($f['option']['image_multiple']) && $f['option']['image_multiple'] == 1) {
                                $files = '';
                                if (isset($_POST['curr' . $field])) {
                                    $curr = '';
                                    for ($i = 0; $i < count($_POST['curr' . $field]); $i++) {
                                        $files .= $_POST['curr' . $field][$i] . ',';
                                    }
                                }

                                $destinationPath = '.' . $f['option']['path_to_upload'];
                                if (count($request->file($f['field'])) >= 1) {

                                    $destinationPath = '.' . $f['option']['path_to_upload'];
                                    foreach ($_FILES[$field]['tmp_name'] as $key => $tmp_name) {
                                        $file_name = $_FILES[$field]['name'][$key];
                                        $file_tmp = $_FILES[$field]['tmp_name'][$key];
                                        if ($file_name != '') {
                                            //move_uploaded_file($file_tmp,$destinationPath.'/'.$file_name);
                                            //echo  $file_name.'<br />';
                                            $file = $request->file($field)[$key];
                                            $filename = $file->getClientOriginalName();
                                            $extension = $file->getClientOriginalExtension(); //if you need extension of the file
                                            $rand = rand(1000, 100000000);
                                            $newfilename = strtotime(date('Y-m-d H:i:s')) . '-' . $rand . '.' . $extension;
                                            $files .= $newfilename . ',';

                                            $uploadSuccess = $file->move($destinationPath, $newfilename);


                                            if ($f['option']['resize_width'] != '0' && $f['option']['resize_width'] != '') {
                                                if ($f['option']['resize_height'] == 0) {
                                                    $f['option']['resize_height'] = $f['option']['resize_width'];
                                                }
                                                $orgFile = $destinationPath . '/' . $newfilename;
                                                \SiteHelpers::cropImage($f['option']['resize_width'], $f['option']['resize_height'], $orgFile, $extension, $orgFile);
                                            }
                                        }
                                    }


                                }
                                if ($files != '')
                                    $files = substr($files, 0, strlen($files) - 1);
                                $data[$field] = $files;


                            } else {

                                if (!is_null($request->file($field))) {
                                    $file = $request->file($field);
                                    $destinationPath = '.' . $f['option']['path_to_upload'];
                                    $filename = $file->getClientOriginalName();
                                    $extension = $file->getClientOriginalExtension(); //if you need extension of the file
                                    $rand = rand(1000, 100000000);
                                    $newfilename = strtotime(date('Y-m-d H:i:s')) . '-' . $rand . '.' . $extension;


                                    $uploadSuccess = $file->move($destinationPath, $newfilename);


                                    if ($f['option']['resize_width'] != '0' && $f['option']['resize_width'] != '') {
                                        if ($f['option']['resize_height'] == 0) {
                                            $f['option']['resize_height'] = $f['option']['resize_width'];
                                        }
                                        $orgFile = $destinationPath . '/' . $newfilename;
                                        \SiteHelpers::cropImage($f['option']['resize_width'], $f['option']['resize_height'], $orgFile, $extension, $orgFile);
                                    }

                                    if ($uploadSuccess) {
                                        $data[$field] = $newfilename;
                                    }
                                }
                            }

                        }
                    }

                    // Handle Checkbox input
                    if ($f['type'] == 'checkbox') {
                        if (!is_null($request->{$field})) {
                            $data[$field] = implode(",", $request->input($field));
                        } else {
                            $data[$field] = '0';
                        }
                    }
                    // if post is date
                    if ($f['type'] == 'date') {
                        $data[$field] = date("Y-m-d", strtotime($request->input($field)));
                    }

                    // if post is seelct multiple
                    if ($f['type'] == 'select') {
                        //echo '<pre>'; print_r( $_POST[$field] ); echo '</pre>';
                        if (isset($f['option']['select_multiple']) && $f['option']['select_multiple'] == 1 && $f['option']['is_json'] == 0) {
                            if (isset($_POST[$field])) {
                                $multival = implode(",", $request->input($field));
                                $data[$field] = $multival;

                            }
                        }
                        $data[$field] = $request->input($field);
                    }

                }

            }
        }
        $this->access = $this->model->validAccess($this->info['id'], session('gid'));
        $global = (isset($this->access['is_global']) ? $this->access['is_global'] : 0);

        if ($global == 0)
            $data['entry_by'] = \Session::get('uid');
        /* Added for Compatibility laravel 5.2 */
        $values = array();
        foreach ($data as $key => $val) {
            $values[$key] = $val;
        }
        return $values;

    }


    function postFilter(Request $request)
    {
        $module = $this->module;
        $sort = (!is_null($request->input('sort')) ? $request->input('sort') : '');
        $order = (!is_null($request->input('order')) ? $request->input('order') : '');
        $rows = (!is_null($request->input('rows')) ? $request->input('rows') : '');
        $md = (!is_null($request->input('md')) ? $request->input('md') : '');

        $filter = '?';
        if ($sort != '')
            $filter .= '&sort=' . $sort;
        if ($order != '')
            $filter .= '&order=' . $order;
        if ($rows != '')
            $filter .= '&rows=' . $rows;
        if ($md != '')
            $filter .= '&md=' . $md;


        return Redirect::to($this->data['pageModule'] . $filter);

    }

    function injectPaginate()
    {

        $sort = (isset($_GET['sort']) ? $_GET['sort'] : '');
        $order = (isset($_GET['order']) ? $_GET['order'] : '');
        $rows = (isset($_GET['rows']) ? $_GET['rows'] : '');
        $search = (isset($_GET['search']) ? $_GET['search'] : '');
        $s = (isset($_GET['s']) ? $_GET['s'] : '');

        $appends = array();
        if ($sort != '')
            $appends['sort'] = $sort;
        if ($order != '')
            $appends['order'] = $order;
        if ($rows != '')
            $appends['rows'] = $rows;
        if ($search != '')
            $appends['search'] = $search;
        if ($s != '')
            $appends['s'] = $s;

        return $appends;

    }

    function returnUrl()
    {
        $pages = ($_GET['page'] ?? '');
        $sort = ($_GET['sort'] ?? '');
        $order = ($_GET['order'] ?? '');
        $rows = ($_GET['rows'] ?? '');
        $search = ($_GET['search'] ?? '');
        $quickSearch = ($_GET['s'] ?? '');

        $appends = [];
        if ($pages != '')
            $appends['page'] = $pages;
        if ($sort != '')
            $appends['sort'] = $sort;
        if ($order != '')
            $appends['order'] = $order;
        if ($rows != '')
            $appends['rows'] = $rows;
        if ($search != '')
            $appends['search'] = $search;
        if ($quickSearch != '')
            $appends['s'] = $quickSearch;

        $url = "";
        foreach ($appends as $key => $val) {
            $url .= "&$key=$val";
        }
        return $url;

    }

    public function getRemovecurrentfiles(Request $request)
    {
        $id = $request->input('id');
        $field = $request->input('field');
        $file = $request->input('file');
        if (file_exists('./' . $file) && $file != '') {
            if (unlink('.' . $file)) {
                \DB::table($this->info['table'])->where($this->info['key'], $id)->update(array($field => ''));
            }
            return response()->json(array('status' => 'success'));
        } else {
            return response()->json(array('status' => 'error'));
        }
    }

    public function getRemovefiles($request)
    {
        $files = '.' . $request->input('file');
        if (file_exists($files) && $files != '') {
            unlink($files);
        }
        return response()->json(array('status' => 'success'));
    }


    public function getSearch($mode = 'native')
    {
        if (isset($_GET['type']))
            $mode = $_GET['type'];

        $this->data['tableForm'] = $this->info['config']['forms'];
        $this->data['tableGrid'] = $this->info['config']['grid'];
        $this->data['searchMode'] = $mode;
        $this->data['pageUrl'] = url('/manage/' . $this->module);

        return view('central.module.utility.search', $this->data);

    }

    function getImport(Request $request)
    {
        $task = $request->input('template');
        if ($task != '') {
            $fields = $this->info['config']['forms'];
            // dd($fields);
            $output = fopen('php://output', 'w');
            $head = array();
            foreach ($fields as $f) {
                $head[] = $f['field'] . ($f['required'] == '1' ? '*' : null);
            }

            fputcsv($output, $head);
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename=' . $this->module . '.csv');

        } else {
            $this->data['url'] = url('/manage/' . $this->module);
            $this->data['module'] = $this->module;
            return view('central.module.utility.import', $this->data);
        }

    }

    function postImport($request)
    {

        if (!is_null($request->file('fileimport'))) {
            $file = $request->file('fileimport');
            $filename = $file->getClientOriginalName();
            $uploadSuccess = $file->move('./uploads/', $filename);
            if ($uploadSuccess) {
                $csv = array_map('str_getcsv', file('./uploads/' . $filename));

                $fields = array_map(function ($item) {
                    return trim($item, '*');
                }, $csv[0]);  // set first row as feilds

                unset($csv[0]);
                foreach ($csv as $row) {
                    $data = array();
                    for ($i = 0; $i < count($fields); $i++)
                        $data[$fields[$i]] = $row[$i];

                    $this->model->insertRow($data, $row[0]);
                }

                return response()->json(array('status' => 'success', 'message' => 'Csv Imported Successful !'));
            } else {
                return response()->json(array('status' => 'error', 'message' => 'Upload Failed!'));
            }
        } else {
            return response()->json(array('status' => 'error', 'message' => 'Please select file to Upload!'));
        }

    }

    public function getExpotion()
    {
        $this->data['pageUrl'] = url($this->data['pageModule']);
        return view('central.module.utility.export', $this->data);
    }

    public function getExport(Request $request, $t = 'excel')
    {
        //TODO: Handle Old Returns

        set_time_limit(0);
        if (!is_null($request->input('filter')))
            return $this->getExpotion();

        $t = $request->input('do');
        $this->access = $this->model->validAccess($this->info['id'], session('gid'));

        if (isset($this->access['is_' . $t])) {
            if ($this->access['is_' . $t] == 0)
                return redirect('dashboard')->with('message', __('core.note_restric'))->with('status', 'error');
        } else {
            return redirect('dashboard')->with('message', __('core.note_restric'))->with('status', 'error');
        }

        $filter = '';
        if (!is_null($request->input('search'))) {
            $search = $this->buildSearchMessage();
            $filter = $search['param'];
            $this->data['search_map'] = $search['maps'];
        }

        $params = array(
            'params' => $filter,
            'limit' => 99999
        );
        $search_keyword = (!is_null($request->input('s'))) ? strtolower($request->input('s')) : null;
        if ($search_keyword)
            $params['search'] = $search_keyword;
        $filename = $this->module . '_export ' . date('d-m-Y', time());
        return view('central.module.utility.csv', [
            'filename' => $filename,
            'query' => $this->model->buildExportQuery($params),
            'headers' => $this->model->getExportHeaders(),
            'countColumn' => $this->model->getModelCountColumn()
        ]);
    }


    function getLookup($request)
    {
        $id = $request->input('param');
        $args = explode("-", $id);
        if (count($args) >= 2) {

            $model = '\\App\\Models\\' . ucwords($args['3']);
            $model = new $model();
            $info = $model->makeInfo($args['3']);
            $data['pageTitle'] = $info['title'];
            $data['pageNote'] = $info['note'];
            $params = array(
                'params' => " And " . $args['4'] . "." . $args['5'] . " ='" . $args['6'] . "'",
                //'global'	=> (isset($this->access['is_global']) ? $this->access['is_global'] : 0 )
            );
            $results = $model->getRows($params);
            $data['access'] = $model->validAccess($info['id']);
            $data['rowData'] = $results['rows'];
            $data['tableGrid'] = $info['config']['grid'];
            $data['tableForm'] = $info['config']['forms'];
            $data['colspan'] = \SiteHelpers::viewColSpan($info['config']['grid']);
            $data['nested_subgrid'] = (isset($info['config']['subgrid']) ? $info['config']['subgrid'] : array());
            //print_r($data['nested_subgrid']);exit;
            $data['id'] = $args[6];
            $data['key'] = $info['key'];
            //$data['ids']		= 'md'-$info['id'];
            return view('central.module.utility.masterdetail', $data);

        } else {
            return 'Invalid Argument';
        }
    }


    function detailview($model, $detail, $id)
    {

        $info = $model->makeInfo($detail['module']);
        $params = array(
            'params' => [$detail['key'] . ':' . "equal" . ':' . $id],
            'global' => (isset($this->access['is_global']) ? $this->access['is_global'] : 0),
        );
        $results = $model->getRows($params);

        $data['rowData'] = $results['rows'];
        $data['tableGrid'] = $info['config']['grid'];
        $data['tableForm'] = $info['config']['forms'];

        return $data;


    }


    function detailviewsave($model, $request, $detail, $id)
    {

        $info = $model->makeInfo($detail['module']);
        $relation_key = $info['key'];
        //@dump($info);
        $access = $model->validAccess($info['id'], session('gid'));


        if ($access['is_add'] == '1' && $access['is_edit'] == '1') {
            $str = $info['config']['forms'];
            $global = (isset($access['is_global']) ? $access['is_global'] : 0);
            $total = isset($request['counter']) ? count($request['counter']) : 0;
            $mkeys = array();

            $deleteIds = explode(',', trim($request['masterdetail_delete'], ','));

            foreach ($deleteIds as $deleteId) {
                if ($deleteId > 0)
                    $model->destroy($deleteId);
                // dd([$detail['master_key']=>$deleteId]);
                // $model->delete( [$detail['master_key']=>$deleteId] );
            }
            $i = 1;
            if (!isset($request['bulk_' . $detail['master_key']]))
                return;
            foreach ($request['bulk_' . $detail['master_key']] as $idKey => $rowVal) {


                $data = array();
                foreach ($str as $f) {
                    $field = $f['field'];
                    if ($f['view'] == 1) {
                        if (isset($request['bulk_' . $field][$idKey])) {

                            $data[$f['field']] = $request['bulk_' . $field][$idKey];

                        }
                    }
                    $data[$detail['key']] = $id;
                }

                $rules = self::validateForm($str);
                $validator = Validator::make($data, $rules);


                if ($validator->passes()) {
                    $data[$detail['key']] = $id;
                    if ($global == 0)
                        $data['entry_by'] = \Session::get('uid');

                    if ($detail['module'] == 'storecashback')
                        $data['rate_amount'] = round(($data['rate_amount_network'] * $request['cashback_percent']) / 100, 2);


                    $model->insertRow($data, $rowVal);
                } else {

                    return redirect('/manage/' . $this->module . '/' . $id . '/edit')
                        ->with('message', __('core.note_error'))->with('status', 'error')
                        ->withErrors($validator)->withInput();

                }

            }

            if ($detail['module'] == 'storecashback') {
                $this->updateCashbackInfo($id);
            }

        }


    }

    function updateCashbackInfo($store_id)
    {
        $store = \App\Models\stores::find($store_id);
        $storeCashback = \App\Models\storecashback::where('store_id', $store_id)->where('enabled', 1)->orderBy('rate_amount_network', 'DESC')->get();
        $total_cbs = $storeCashback->count();
        $storeCashback = $storeCashback->first();
        if (empty($storeCashback)) {
            if ($store->cb_status) {
                throw ValidationException::withMessages([
                    'cashback_status' => 'You must have at least one enabled store cashback'
                ]);
            } else {
                return;
            }
        }

        ($total_cbs > 1) ? $rate_type = 'upto' : $rate_type = 'flat';

        $current_cb = round((($storeCashback->rate_amount_network) * $store->cashback_percent) / 100, 2);
        $amount_type = $storeCashback->rate_type;


        if ($current_cb == $store->current_cb && $rate_type == $store->rate_type && $amount_type == $store->amount_type)
            return;
        else {
            $store->was_cb = $store->amount_type . '|' . $store->current_cb;
            $store->current_cb = $current_cb;
            $store->amount_type = $amount_type;
            $store->rate_type = $rate_type;
            $store->save();
        }


    }

    public function liveSearch($request)
    {
        $query = '';
        $forms = $this->info['config']['forms'];
        $keyword = trim($request->input('s'));
        if (!is_null($request->input('search')))
            $keyword = trim($request->input('search')['value']);

        $i = 0;
        foreach ($forms as $form) {
            if ($form['search'] == '1') {
                if ($i == 0) {
                    $query .= " AND ( " . $form['alias'] . "." . $form['field'] . " LIKE '%" . trim($keyword) . "%' ) ";
                } else {
                    $query .= " OR ( " . $form['alias'] . "." . $form['field'] . " LIKE '%" . trim($keyword) . "%' ) ";
                }
                $i++;
            }

        }
        return $query;
    }


    public function liveModelSearch($request)
    {
        $searchParams = [];
        $forms = $this->info['config']['forms'];
        $keyword = trim($request->input('s'));
        if (!is_null($request->input('search')))
            $keyword = trim($request->input('search')['value']);

        $i = 0;
        foreach ($forms as $form) {
            if ($form['search'] == '1') {
                if ($i == 0) {
                    $query .= " AND ( " . $form['alias'] . "." . $form['field'] . " LIKE '%" . trim($keyword) . "%' ) ";
                } else {
                    $query .= " OR ( " . $form['alias'] . "." . $form['field'] . " LIKE '%" . trim($keyword) . "%' ) ";
                }
                $i++;
            }

        }
        return $query;
    }

    public function grab($request, $args = array())
    {

        $this->access = $this->access($this->info['id']);
        $sort = (!is_null($request->input('sort')) ? $request->input('sort') : $this->info['setting']['orderby']);
        $order = (!is_null($request->input('order')) ? $request->input('order') : $this->info['setting']['ordertype']);
        // End Filter sort and order for query
        // Filter Search for query
        $filter = '';
        $filter .= (isset($args['params']) ? $args['params'] : '');
        if (!is_null($request->input('search'))) {
            $search = $this->buildSearchMessage(true);
            $filter = $search['param'];

            $this->data['search_map'] = $search['maps'];
        }

        $search_keyword = (!is_null($request->input('s'))) ? $request->input('s') : null;

        $limit = (!is_null($request->input('rows')) ? filter_var($request->input('rows'), FILTER_VALIDATE_INT) : static::$per_page);
        $page = $request->input('page', 1);
        if (isset($this->access['is_search']) && $this->access['is_search'] == 1 && $this->access['is_view'] == 0) {
            $limit = 5;
            $page = 1;
        }
        $params = array(
            'page' => $page,
            'limit' => $limit,
            'sort' => $sort,
            'search' => $search_keyword,
            'order' => $order,
            'params' => $filter,
            'global' => (isset($this->access['is_global']) ? $this->access['is_global'] : 0)
        );
        if (is_null($search_keyword) && isset($this->access['is_search']) && $this->access['is_search'] == 1 && $this->access['is_view'] == 0) {
            // Get Query
            $results['rows'] = [];
            $results['total'] = 0;
        } elseif (isset($this->access['is_search']) && $this->access['is_search'] == 1 && $this->access['is_view'] == 0) {
            $results = $this->model->getRows($params, session('uid'));

        } else {
            $results = $this->model->getRows($params, session('uid'));
        }
        // Build pagination setting
        $pagination = new Paginator($results['rows'], $results['total'], $params['limit']);
        if ($this->info['type'] == 'ajax' || $this->info['type'] == 'hybrid') {
            $pagination->setPath($this->module . '/data');
        } else {
            $pagination->setPath($this->module);
        }
        $this->data['param'] = $params;
        $this->data['rowData'] = $results['rows'];
        // Build Pagination
        if (isset($this->access['is_search']) && $this->access['is_search'] == 1 && $this->access['is_view'] == 0)
            $pagination = false;
        $this->data['pagination'] = $pagination;
        // Build pager number and append current param GET
        $this->data['pager'] = $this->injectPaginate();
        // Row grid Number
        $this->data['i'] = ($page * $params['limit']) - $params['limit'];
        // Grid Configuration
        $this->data['tableGrid'] = $this->info['config']['grid'];
        $this->data['tableForm'] = $this->info['config']['forms'];
        $this->data['colspan'] = \SiteHelpers::viewColSpan($this->info['config']['grid']);
        // Group users permission
        $this->data['access'] = $this->access;
        // Detail from master if any
        $this->data['fields'] = \SiteHelpers::fieldLang($this->info['config']['grid']);
        // Master detail link if any
        $this->data['subgrid'] = (isset($this->info['config']['subgrid']) ? $this->info['config']['subgrid'] : array());
        $this->data['setting'] = $this->info['setting'];

        $this->data['insort'] = $sort;
        $this->data['inorder'] = $order;

        return $this->data;
    }

    public function hook($request, $id = null)
    {
        $this->access = $this->access($this->info['id']);
        if ($id)
            $row = $this->model->getRow($id);
        else
            $row = null;
        if ($row) {
            $this->data['row'] = $row;

            $this->data['fields'] = \SiteHelpers::fieldLang($this->info['config']['grid']);
            $this->data['id'] = $id;
            $this->data['access'] = $this->access;
            $this->data['subgrid'] = (isset($this->info['config']['subgrid']) ? $this->info['config']['subgrid'] : array());

            if (isset($this->info['config']['subform']))
                $this->data['subform'] = $this->detailview($this->modelview, $this->info['config']['subform'], $id);

            $this->data['fields'] = \SiteHelpers::fieldLang($this->info['config']['grid']);
            if (is_numeric($id))
                $this->data['prevnext'] = array('prev' => $id - 1, 'next' => $id + 1);
            $this->data['setting'] = $this->info['setting'];

        }
        return $this->data;
    }

    function copy($request)
    {
        foreach (\DB::select("SHOW COLUMNS FROM " . $this->info['table']) as $column) {
            if ($column->Field != $this->info['key'] && $column->Field != 'default')
                $columns[] = $column->Field;
        }

        if (count($request->input('ids')) >= 1) {
            $toCopy = implode(",", $request->input('ids'));
            $sql = "INSERT INTO " . $this->info['table'] . " (" . implode(",", $columns) . ") ";
            $sql .= " SELECT " . implode(",", $columns) . " FROM " . $this->info['table'] . " WHERE " . $this->info['key'] . " IN (" . $toCopy . ")";
            \DB::select($sql);
            return ['message' => __('core.note_success'), 'status' => 'success'];
        } else {
            return ['message' => __('Please select row to copy'), 'status' => 'error'];
        }

    }

    function access($id)
    {
        return Cache::rememberForever('GetAccess_' . $id . '_' . session('gid'), function () use ($id) {

            $row = \DB::table('tb_groups_access')->where('module_id', $id)->where('group_id', session('gid'))->get();
            if (count($row) >= 1) {
                $row = $row[0];
                if ($row->access_data != '') {
                    $data = json_decode($row->access_data, true);
                } else {
                    $data = array();
                }
                return $data;

            } else {
                return false;
            }

        });


    }


    function RemoveFilterComma($data)
    {
        $filter = rtrim(str_replace(",,", ",", $data), ',');
        return $filter;
    }

    public function doPaginate($record, $perPage)
    {
        $total = count($record);

        $currentpage = \Request::get('page', 1);
        $offset = ($currentpage * $perPage) - $perPage;

        $itemstoshow = array_slice($record, $offset, $perPage);

        $data = new LengthAwarePaginator($itemstoshow, $total, $perPage);

        $data->setPath(url('/') . '/' . request()->path());
        return ['data' => $data, 'totalRecord' => $total];
    }

    public function doPaginateOnly($record, $perPage, $total)
    {
        $currentpage = \Request::get('page', 1);
        $offset = ($currentpage * $perPage) - $perPage;

        $data = new LengthAwarePaginator($record, $total, $perPage);

        $data->setPath(url('/') . '/' . request()->path());
        return ['data' => $data, 'totalRecord' => $total];
    }

    public function reCaptcha($request)
    {
        if (!is_null($request['g-recaptcha-response'])) {
            $api_url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . config('settingConfig.cnf_recaptchaprivatekey') . '&response=' . $request['g-recaptcha-response'];
            $response = @file_get_contents($api_url);
            $data = json_decode($response, true);

            return $data;
        } else {
            return false;
        }
    }

}
