<?php

namespace Encore\Admin\Middleware;

use Encore\Admin\Auth\Database\OperationLog as OperationLogModel;
use Encore\Admin\Facades\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Models\ConfigType;

class LogOperation
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure                 $next
     *
     * @return mixed
     */
    public function handle(Request $request, \Closure $next)
    {
        if ($this->shouldLogOperation($request)) {
            $log = [
                'user_id' => Admin::user()->id,
                'route'    => $request->route()->getName(),
                'path'    => substr($request->path(), 0, 255),
                'method'  => $request->method(),
                'ip'      => $request->getClientIp(),
                'input'   => json_encode($request->input()),
                'message'   => $this->getMessage($request),
            ];
            try {
                OperationLogModel::create($log);
            } catch (\Exception $exception) {
                // pass
            }
        }

        return $next($request);
    }

    /**
     * @param Request $request
     *
     * @return bool
     */
    protected function shouldLogOperation(Request $request)
    {
        if(!$request->route()->getName())
        {
            return false;
        }
        return config('admin.operation_log.enable')
            && !$this->inExceptArray($request)
            && $this->inAllowedMethods($request->method())
            && Admin::user();
    }

    /**
     * Whether requests using this method are allowed to be logged.
     *
     * @param string $method
     *
     * @return bool
     */
    protected function inAllowedMethods($method)
    {
        $allowedMethods = collect(config('admin.operation_log.allowed_methods'))->filter();

        if ($allowedMethods->isEmpty()) {
            return true;
        }

        return $allowedMethods->map(function ($method) {
            return strtoupper($method);
        })->contains($method);
    }

    /**
     * Determine if the request has a URI that should pass through CSRF verification.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return bool
     */
    protected function inExceptArray($request)
    {
        foreach (config('admin.operation_log.except') as $except) {
            if ($except !== '/') {
                $except = trim($except, '/');
            }
            $methods = [];
            if (Str::contains($except, ':')) {
                list($methods, $except) = explode(':', $except);
                $methods = explode(',', $methods);
            }
            $except = config('admin.route.prefix').'/'.$except;
            $methods = array_map('strtoupper', $methods);
            if ($request->is($except) &&
                (empty($methods) || in_array($request->method(), $methods))) {
                return true;
            }
        }
        return false;
    }


    protected function getMessage(Request $request)
    {
        $prefixArray=explode('/', $request->route()->getPrefix());
        $fileName=count($prefixArray) == 1?'admin.php':$prefixArray[1].'.php';
        if (!file_exists(app_path('Admin/logs/'.$fileName))) {
            return "无描述信息";
        }
        $messageArray=include app_path('Admin/logs/'.$fileName);
        $params=array_merge($request->toArray(), $request->route()->parameters());
        $message=array_get($messageArray, $request->route()->getName(), "无描述信息");
        if (is_array($message)) {
            if (isset($message['model'])) {
                $model=app($message['model']);
                if(isset($message['select'])) {
                    $res=$model->whereIn('id',explode(',' ,$params[$message['primary_key']]))->pluck($message['select'])->toArray();
                    if($res)
                    {
                        $params = array_merge($params,[$message['select']=>implode(',',$res)]);
                    }
                }else {
                    $res=$model->find($params[$message['primary_key']])->toArray();
                    if($res)
                    {
                        $params = array_merge($params,$res);
                    }
                }
            }
            if(isset($message['params'])){
                foreach ($message['params'] as $k=>$v)
                {
                    if($params[$k] || $params[$k]==0){
                        $params[$k] = $v[$params[$k]];
                    }
                }
            }
            if(isset( $message['message']))
            {
                $message = $message['message'];
            }
        }
        if($request->route()->getName() == 'jobfair.singedupdate')
        {
            $hash_id = $params['hash_id'];
            $hash_array = explode('/',$hash_id);
            $hash_id = $hash_array[count($hash_array)-1];
            $res = hashid_decode($hash_id);
            if($res) {
                $message .= ','.($res['utype'] == 1 ? '企业' : '求职者') .'id为'.$res['id'];
            }
        }
        return strip_tags(render_template($message, $params));
    }

}
