_viewname.'.'.$viewname)) { return view($this->_viewname.'.'.$viewname); } else { return view('common.'.$viewname); } } protected function getlambda($type, $service, $module, $url, $data = []) { return LambdaRequest::signedrequest($type, $service, $module.'/'.$url, $data); if($url == 'dropdown' && $this->_request->session()->has($service.'-'.$module.'-'.$url) ) { return $this->_request->session()->get($service.'-'.$module.'-'.$url); } elseif($url == 'dropdown'){ $res = LambdaRequest::signedrequest($type, $service, $module.'/'.$url, $data); $this->_request->session()->put($service.'-'.$module.'-'.$url, $res); return $res; } else { return LambdaRequest::signedrequest($type, $service, $module.'/'.$url, $data); } } public function action($action, Request $request) { $this->_request = $request; switch ($action) { case 'edit': return $this->form('edit', $request->input('id')); break; case 'addnew': return $this->form('new'); break; case 'delete': return $this->delete($request->input('id')); break; default: return $this->{$action}($request); break; } } public function postaction($action, Request $request) { $this->_request = $request; switch ($action) { case 'edit': return $this->save('edit', $request ); break; case 'addnew': return $this->save('new', $request ); break; default: return $this->{'post'.$action}($request); break; } } public function list(Request $request) { $response = LambdaRequest::signedrequest('get', $this->_service, $this->_module.'/get_all'); //echo '
'; print_r($response); exit;
        if($response->statusCode == 401) {
            return redirect('/unauthorised');
        }
    	$fields = $this->get_list_fields();
        //echo '
'; print_r($fields); exit;
        return $this->view($this->_listtype)->with([
        	'title' => $this->_title,
        	'fields' => $fields,
        	'base_url' => $this->_base_url,
        	'items' => $response->data->items,
            'buttons' => $this->get_list_buttons()
        ]);
    }

    public function ajaxlist(Request $request) {
        $params = $request->input();
        $search = [];
        foreach($params['columns'] as $col) {
            if($col['search']['value'] != '') {
                $search[$col['data']] = $col['search']['value'];
            }
        }
        $fields = $this->get_list_fields();
        $response = LambdaRequest::signedrequest('get', $this->_service, $this->_module.'/get_all', ['start' => $params['start'], 'length' => $params['length'], 'search' => json_encode($search), 'keyword' => $params['search']['value']  ]);
        Log::debug(print_r($response, true));

        $users = [];
        foreach($response->data->items as $item) {
            $user = [];
            if(isset($item->id)) {
                $user['id'] = $item->id;
            }
            foreach($fields as $field => $props){
                if($field != 'actions') {
                    switch($props['type']){
                        case('image'):
                            $user[$field] = ' ';
                            break;
                        case('text'):
                        case('select'):
                        case('number'):
                            $user[$field] = isset($item->{$field}) ? $item->{$field} : '';
                            break;
                        case('date'):
                            $user[$field] = date("d M Y", strtotime($item->{$field}));
                            break;
                    }
                } else {
                    $user['actions'] = [];
                    foreach($props['buttons'] as $key => $button){
                        switch($button) {
                            case 'edit':
                                $user['actions'][] = ['link' => '/edit?id='.$item->id, 'icon' => 'square-edit-outline text-warning'];
                                break;
                            case 'delete':
                                $user['actions'][] = ['link' => '/delete?id='.$item->id, 'icon' => 'delete text-danger'];
                                break;
                            default:
                                $querystring = $button['querystring'];
                                foreach((array)$item as $k => $v) {
                                    if(strpos($querystring,'{'.strtoupper($k).'}') !== false)
                                        $querystring = str_replace('{'.strtoupper($k).'}', $v, $querystring);
                                }
                                $user['actions'][] = ['link' => '/'.$key.'?'.$querystring, 'icon' => $button['icon']];
                                break;
                        }
                    }
                }
            }
            $users[] = $user;
        }

        return response()->json(['data' => $users, 'iTotalRecords' => $response->data->count, 'iTotalDisplayRecords' => $response->data->count]);
    }

    public function unauthorised() {
        return view('common.unauthorised');
    }

    public function import(Request $request) {
        return $this->view('import')->with([
            'title' => $this->_title,
            'base_url' => $this->_base_url,
        ]);
    }

    public function postimport(Request $request) {
        if( $request->file('importfile') ) {
            $path = $request->file('importfile')->store('user_import', 's3');
            $user = Auth::user();
            $id = DB::table('import_jobs')->insertGetId(['user_id' => $user->id, 'domain' => $user->domain, 'service' => $this->_service, 'module' => $this->_module, 'filepath' => $path, 'status' => 1 ]);
            Importdata::dispatch($id);
            return redirect($this->_base_url.'/importprocess?id='.$id)->withMessage('Successfully Uploaded !!!');
        } else {
            return \Redirect::back()->withMessage('Some Error occured!');
        }
    }

    public function importprocess(Request $request) {
        $id = $request->input('id', 0);
        $import = DB::table('import_jobs')->where('id', $id)->first();
        return $this->view('importprocess')->with(['baseurl' => $this->_base_url, 'id' => $id]);
    }

    public function importstatus(Request $request) {
        $id = $request->input('id', 0);
        $import = DB::table('import_jobs')->where('id', $id)->first();
        return response()->json($import);
    }

    

    public function importmap(Request $request) {
        $path = $request->session()->get('user_import_path');
        $csv = Reader::createFromPath(storage_path('app') .'/' . $path, 'r');
        $csv->setHeaderOffset(0);

        $header = $csv->getHeader(); //returns the CSV header record
        $records = $csv->getRecords(); //returns all the CSV records as an Iterator object
        $fields = $this->get_import_fields($records);
        // echo '
'; 
        // foreach($records as $record){
        //     print_r($record);
        // }
        // exit;
        return $this->view('importmap')->with([
            'title' => $this->_title,
            'base_url' => $this->_base_url,
            'records' => $records,
            'fields' => $fields,
        ]);
    }

    public function postimportmap(Request $request) {
        $post = $request->except('_token');
        $post = $this->flip_row_col_array($post);
        $created = 0;
        $updated = 0;
        $count = 0;
        $total = sizeof($post);

        while($count < $total) {
            $tempdata = array_slice($post, $count, 10);
            Log::debug(print_r($tempdata, true));
            $response = LambdaRequest::signedrequest('post', $this->_service, $this->_module.'/import', $tempdata);
            Log::debug(print_r($response, true));
            $count = $count + 10;
            $created = $created + $response->data->created_count;
            $updated = $updated + (isset($response->data->updated_count) ? $response->data->updated_count : 0);
            Log::debug(print_r(['$count' => $count, '$created' => $created, '$updated' => $updated], true));
        }

        //echo '
'; print_r($response); exit;
        if($response->statusCode == 200 && $response->status == "success") {
            return redirect($this->_base_url.'s')->withMessage('Successfully Imported ' .$created. ' records and Updated ' .$updated. ' records out of ' .$total. ' records!!!');
        } else {
            return \Redirect::back()->withMessage('Some Error occured!');
        }
    }

    private function flip_row_col_array($array) {
        $out = array();
        foreach ($array as  $rowkey => $row) {
            foreach($row as $colkey => $col){
                $out[$colkey][$rowkey]=$col;
            }
        }
        return $out;
    }

    protected function get_list_buttons() {
        return [ ['title' => 'Add New', 'link' => $this->_base_url.'/addnew' ] ];
    }

    protected function getRoleNameMap(): array
    {
        $roles = $this->getlambda('get', 'ums', 'roles', 'dropdown');
        $map = [];
        if (isset($roles->data->items) && is_array($roles->data->items)) {
            foreach ($roles->data->items as $role) {
                if (!isset($role->id)) {
                    continue;
                }
                $map[$role->id] = $role->name ?? $role->id;
            }
        }

        return $map;
    }

    protected function formatAssignedRoles($raw, array $roleMap = null): string
    {
        if ($roleMap === null) {
            $roleMap = $this->getRoleNameMap();
        }
        if ($raw === null || $raw === '') {
            return '-';
        }
        if (is_string($raw)) {
            $ids = preg_split('/[#~,]/', $raw, -1, PREG_SPLIT_NO_EMPTY);
        } elseif (is_array($raw)) {
            $ids = array_values(array_filter(array_map('strval', $raw), function ($id) {
                return $id !== '';
            }));
        } else {
            return '-';
        }

        $names = [];
        foreach ($ids as $id) {
            $names[] = $roleMap[$id] ?? $id;
        }

        return empty($names) ? '-' : implode(', ', $names);
    }

    public function form($type, $id = null) {
    	$values = [];
    	if($type == 'edit') {
    		$response = LambdaRequest::signedrequest('get', $this->_service, $this->_module.'/get_one', ['id' => $id]);
    		$values = $response->data->item;
            //echo '
'; print_r($values); exit;
    	}
        //echo '
'; print_r($values); exit;
        $data = $this->_beforeform($type, $values);
    	$fields = $this->get_form_fields($type, $values);
        //echo '
'; print_r($fields); exit;
        return $this->view('form')->with([
        	'title' => $this->_title,
        	'mode' => $type,
        	'fields' => $fields,
        	'base_url' => $this->_base_url,
        	'item' => $values,
        ]);
    }

    public function save($type, $request ) {
    	if($type == 'edit') {
    		$url = '/update';
    	} else {
    		$url = '/create';
    	}
        $data = $this->_beforesave($type, $request);
        //echo '
'; print_r($data); exit;
    	$response = LambdaRequest::signedrequest('post', $this->_service, $this->_module.$url, $data);
        //echo '
'; print_r($response); exit;
    	if($response->statusCode == 200 && $response->status == "success") {
            //echo '
'; print_r($response); exit;
    		//return redirect($this->_base_url.'/edit?id='.$response->data->item->id)->withMessage('Successfully Saved !!!');
            return redirect($this->_base_url.'s')->withMessage('Successfully Saved !!!');
    	} else {
            return redirect($this->_base_url.'s')->withError('Some Error occured! '. $response->message);
    		//return \Redirect::back()->withMessage('Some Error occured!');
    	}
    }

    public function delete($id) {
        //echo '
'; print_r($id); exit;
        $response = LambdaRequest::signedrequest('get', $this->_service, $this->_module.'/delete', ['id' => $id]);
        //echo '
'; print_r($response); exit;
        if($response->statusCode == 200 && $response->status == "success") {
            //echo '
'; print_r($response); exit;
            return redirect($this->_base_url.'s')->withMessage('Successfully Marked Deleted !!!');
        } else {
            return redirect($this->_base_url.'s')->withError('Some Error occured! '. $response->message);
            //return \Redirect::back()->withMessage('Some Error occured!');
        }
    }

    protected function _beforesave($type, $request) {
        return $request->except('_token');
    }
    protected function _beforeform($type, $values) {
        return $values;
    }

    protected function _uploadMedia($request, $name = 'image', $folder = 'image', $prefix = '')
    {
        $path = '';
        try {
            $formdata = $request->session()->get('formdata') ?? (object)[];
            $employeeCode = $formdata->employee_code ?? null;
            $employeeName = $formdata->employee_name ?? null;
            $hasEmp = !empty($employeeCode) && !empty($employeeName);
            $empName = $hasEmp ? preg_replace('/[^A-Za-z0-9\-]/', '_', $employeeName) : '';
            if (is_array($request->file($name))) {
                $paths = [];
                foreach ($request->file($name) as $k => $file) {
                    if ($hasEmp) {
                        $filename = !empty($prefix)
                            ? $prefix . '_' . $employeeCode . '_' . $empName . '_' . $k . '_' . $file->hashName()
                            : $employeeCode . '_' . $empName . '_' . $k . '_' . $file->hashName();
                    } else {
                        $filename = !empty($prefix)
                            ? $prefix . '_' . $k . '_' . $file->hashName()
                            : $k . '_' . $file->hashName();
                    }
                    $storedPath = $hasEmp
                        ? $file->storeAs(
                            $folder,
                            $filename,
                            's3'
                        )
                        : $file->store($folder, 's3');

                    $paths[] = env('AWS_URL', 'https://did94hhhcgq1d.cloudfront.net') . '/' . $storedPath;
                }
                $path = implode(',', $paths);
            } else if ($request->file($name)) {
                $file = $request->file($name);
                if ($hasEmp) {
                    $filename = !empty($prefix)
                        ? $prefix . '_' . $employeeCode . '_' . $empName . '_' . $file->hashName()
                        : $employeeCode . '_' . $empName . '_' . $file->hashName();
                } else {
                    $filename = !empty($prefix)
                        ? $prefix . '_' . $file->hashName()
                        : $file->hashName();
                }
                $storedPath = $hasEmp
                    ? $file->storeAs(
                        $folder,
                        $filename,
                        's3'
                    )
                    : $file->store($folder, 's3');
                $path = env('AWS_URL', 'https://did94hhhcgq1d.cloudfront.net') . '/' . $storedPath;
            }
        } catch (AwsException $e) {
            Log::debug($e->getMessage());
        }
        return $path;
    }

    /**
     * Copy an S3 object to a new key prefixed with neblogistic row id. The original object is left in place.
     * Expects a public URL whose path matches the object key under the configured AWS_URL / s3 disk.
     *
     * @param  string|null  $publicUrl
     * @param  int|string  $insertedId
     * @return string|null New public URL for the copy, or original URL if copy skipped/failed
     */
    protected function neblogisticPrefixRequestLetterOnS3($publicUrl, $insertedId)
    {
        if ($publicUrl === null || $publicUrl === '') {
            return $publicUrl;
        }

        $baseUrl = rtrim(env('AWS_URL', 'https://did94hhhcgq1d.cloudfront.net'), '/');
        $publicUrl = trim($publicUrl);

        $key = null;
        if (strpos($publicUrl, $baseUrl . '/') === 0) {
            $key = substr($publicUrl, strlen($baseUrl) + 1);
        } else {
            $path = parse_url($publicUrl, PHP_URL_PATH);
            if (is_string($path) && $path !== '') {
                $key = ltrim($path, '/');
            }
        }

        if ($key === null || $key === '') {
            return $publicUrl;
        }

        $dir = dirname($key);
        $baseName = basename($key);
        $prefix = (string) $insertedId . '_';
        if (strpos($baseName, $prefix) === 0) {
            return $publicUrl;
        }

        $newBaseName = $prefix . $baseName;
        $newKey = ($dir === '.' || $dir === '') ? $newBaseName : $dir . '/' . $newBaseName;

        try {
            $disk = Storage::disk('s3');
            if (!$disk->exists($key)) {
                Log::warning('neblogistic S3 copy: source key not found', ['key' => $key]);

                return $publicUrl;
            }
            if ($disk->exists($newKey)) {
                Log::warning('neblogistic S3 copy: destination already exists', ['newKey' => $newKey]);

                return $publicUrl;
            }
            $disk->copy($key, $newKey);

            return $baseUrl . '/' . $newKey;
        } catch (\Throwable $e) {
            Log::error('neblogistic S3 copy failed: ' . $e->getMessage(), [
                'from' => $key,
                'to' => $newKey ?? null,
            ]);

            return $publicUrl;
        }
    }

    // protected function _uploadMedia($request, $name = 'image', $folder = 'image') {

    //     // Log::debug(['_uploadMedia']);
    //     // Log::debug($request->all());
    //     // $formdata = $request->session()->get('formdata');
    //     // Log::debug(['formdatasession']);
    //     // Log::debug(print_r($formdata));

    //     $path = '';
    //     try {
    //         if(is_array($request->file($name))) {
    //             $paths = [];
    //             foreach($request->file($name) as $file) {
    //                 $path = $file->store($folder, 's3');
    //                 $path = env('AWS_URL', 'https://did94hhhcgq1d.cloudfront.net').'/'.$path;
    //                 $paths[] = $path;
    //             }
    //             $path = implode(',', $paths);
    //         } else if( $request->file($name) ) {
    //             $path = $request->file($name)->store($folder, 's3');
    //             $path = env('AWS_URL', 'https://did94hhhcgq1d.cloudfront.net').'/'.$path;
    //         }
    //     } catch (AwsException $e) {
    //         Log::debug($e->getMessage());
    //     } 
    //     return $path;
    // }

    protected function _uploadMediaLocal($request, $name = 'image', $folder = 'image') {
        $path = '';
        try {
            if( $request->file($name) ) {
                $path = $request->file($name)->store($folder);
                $path = '/'.str_replace('public', 'storage', $path);
            }
        } catch (AwsException $e) {
            Log::debug($e->getMessage());
        } 
        return $path;
    }
}