<?php

namespace App\Http\Modules\Admin;

use Auth;
use App\Models\Admin;
use App\Models\AdminLog;

use App\Http\Rules\Admin\Image64Check;
use App\Http\Rules\Admin\ExistCheck;

use App\Http\Helpers\General;
use App\Http\Helpers\Hasher;
use App\Http\Helpers\ImageHandel;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;

use App\Http\Controllers\Admin\BaseController;

class AdminModule extends BaseController
{
    public function __construct()
    {
        parent::__construct();
    }

    public static function self(Request $request)
    {
    	$self = Auth::guard('admin-api')->user();
    	$self->role_list = $self->getRoleNames();
    	$self->permission_list = $self->getAllPermissions()->pluck('name');

    	unset($self->roles);
    	unset($self->permissions);

    	$data = General::returnData($self);
        return response()->json($data);
    }

    public static function list(Request $request)
    {
        General::storeCachePerviousQuery($request->query(), 'admin_query');
     
        $name = $request->get('name', null);
        $email = $request->get('email', null);
        $status = $request->get('status', []);
        $page = $request->get('page', null);
        $limit = $request->get('limit', 10);

        $query = Admin::query();

        if (strlen($name) > 0) {
            $query->where('name', 'like', '%' . $name . '%');
        }

        if (strlen($email) > 0) {
            $query->where('email', 'like', '%' . $email . '%');
        }

        if (!empty($status) > 0) {
            $query->whereIn('status', $status);
        }

        if (!Auth::guard('admin-api')->user()->hasRole('Shadow Admin')) {
            $query->whereNotIn('id', [1]);
        }

        $query->orderBy('id', 'desc');

        $params = [
            'name' => $name,
            'email' => $email,
            'status' => $status,
            'page' => $page
        ];

        $admin_list = $query->paginate($limit);

        $extract = [];
        foreach ($admin_list as $key => $row) {
            $extract[] = $row;

        }
        $pagination = General::paginationGenerator($admin_list, $params, $extract);

        return $pagination;
    }

    public static function show(Request $request, $hash_id)
    {
        $id = Hasher::decode('admins', $hash_id);
        $admin = Admin::find($id);
        if ($admin) {
            $data = General::returnData($admin, '');
            return response()->json($data);
        }
        return abort(404);
    }

    public static function store(Request $request)
    {
        $validation = AdminModule::validation($request);
        if (!$validation->status) {
            return response()->json($validation, 422);
        }

        DB::beginTransaction();

        $name = $request->input('name');
        $email = $request->input('email');
        $password = $request->input('password');
        $status = $request->input('status');

        $admin = new Admin();
        $admin->name = $name;
        $admin->email = $email;
        $admin->password = bcrypt($password);
        $admin->status = $status;

        // img
        $img = $request->input('img');
        if (!empty($img)) {
            $img = json_encode(ImageHandel::insertImage('admin', $img));
            $admin->img = $img;
            if (!$img) {
                DB::rollBack();
            }
        }

        $admin->created_by = Auth::guard('admin-api')->user()->id;
        $admin->updated_by = Auth::guard('admin-api')->user()->id;
        $admin->save();

        // role
        $role_id = $request->input('role_id');
        $role_id = Hasher::decodeArray('roles', $role_id);
        $admin->syncRoles($role_id);

        // log
        AdminModule::makeLog($admin->id, 'admin (' . Auth::guard('admin-api')->user()->id . ') created');

        DB::commit();

        $query_string = General::getCachePerviousQuery('admin_query');
        $data = General::returnData($admin, $query_string);

        return response()->json($data);
    }

    public static function update(Request $request, $hash_id)
    {
        $id = Hasher::decode('admins', $hash_id);
        $validation = AdminModule::validation($request, $id, 'PUT');
        if (!$validation->status) {
            return response()->json($validation, 422);
        }

        DB::beginTransaction();

        $name = $request->input('name');
        $email = $request->input('email');
        $password = $request->input('password');
        $status = $request->input('status');

        $admin = Admin::find($id);
        $admin->name = $name ?? $admin->name;
        $admin->email = $email ?? $admin->email;
        if (!empty($password)) {
            $admin->password = bcrypt($password);
        }
        $admin->status = $status ?? 2;

        // img
        $img = $request->input('img');
        if (!empty($img)) {
            $remove_image = $admin->img;
            $remove_image = $remove_image ? ImageHandel::removeImage($remove_image) : '';
            $img = json_encode(ImageHandel::insertImage('admin', $img));
            $admin->img = $img;
            if (!$img) {
                DB::rollBack();
            }
        }

        $admin->updated_by = Auth::guard('admin-api')->user()->id;
        $admin->update();

        //role
        $role_id = $request->input('role_id');
        $role_id = Hasher::decodeArray('roles', $role_id);
        $admin->syncRoles($role_id);

        // log
        AdminModule::makeLog($admin->id, 'admin (' . Auth::guard('admin-api')->user()->id . ') updated');

        DB::commit();

        $query_string = General::getCachePerviousQuery('admin_query');
        $data = General::returnData($admin, $query_string);

        return response()->json($data);
    }

    public static function validCheck(Request $request, $hash_id = '', $method = 'POST')
    {
        $id = $hash_id ? Hasher::decode('admins', $hash_id) : '';
        $validation = AdminModule::validation($request, $id, $method);
        if (!$validation->status) {
            return response()->json($validation, 422);
        }
    }

    private static function validation(Request $request, $id = '', $method = 'POST')
    {
        $data = $request->all();
        $rule= [];

        if ($method == 'POST') {
            $rule = [
                // 'img' => 'required',
                'name' => 'required',
                'email' => 'required|email|max:255|unique:admins,email',
                'password' => 'required|min:6|confirmed',
                'role_id' => ['required', new ExistCheck('role')],
            ];
        }

        if ($method == 'PUT') {
            $rule = [
                'img' => '',
                'name' => 'required',
                'email' => 'required|email|max:255|unique:admins,email,' . $id,
                'password' => 'sometimes|confirmed',
                'role_id' => ['required', new ExistCheck('role')],
            ];
        }

        if (!empty($data['img'])) {
            foreach ($data['img'] as $key => $row) {
                $rule['img'.'.'.$key] = ['required', new Image64Check()];
            }
        }

        $validator = Validator::make($data, $rule, config('error_code'));

        $errors = $validator->errors();

        if (!empty($data['img'])) {
            foreach ($data['img'] as $key => $row) {
                if ($errors->first('img'.'.'.$key)) {
                    $errors->add('img', config('error_code.img_error'));
                    break;
                }
            }
        }

        if ($validator->fails()) {
            $data = General::returnErrorData($errors);
            return $data;
        }
        else {
            return (object)['status' => true];
        }
    }

    public static function makeLog($id = '', $remark = '') 
    {
        $entity = Admin::find($id);
        $log = new AdminLog();
        $log->admin_id = $entity->id;
        $log->history = json_encode($entity);
        $log->remark = $remark;
        $log->save();
    }
}
