<?php
declare (strict_types = 1);

namespace app\middleware;

use app\model\UserBehaviorLogModel;
use think\facade\Request;
use Closure;

/**
 * 操作日志中间件
 */
class BehaviorLogMiddleware
{
    // 不记录日志的控制器/方法
    private $excludeActions = [
        // 查询类操作（不改变数据的操作）
        'User/list',
        'User/detail',
        'UserRole/list',
        'UserRole/detail',
        'Game/list',
        'Game/detail',
        'Game/statistics',
        'Game/getPlatforms',
        'Player/list',
        'Player/detail',
        'Player/statistics',
        'Menu/list',
        'Menu/getUserMenus',
        'LoginLog/list',
        'LoginLog/detail',
        'LoginLog/statistics',
        'LoginLog/recentLogs',
        'BehaviorLog/list',
        'BehaviorLog/detail',
        'BehaviorLog/statistics',
        'BehaviorLog/recentLogs',
        'BehaviorLog/getBehaviorTypes',
        // 登录相关
        'User/login',
        'User/logout',
    ];
    
    // 需要过滤的敏感参数
    private $filterParams = [
        'password',
        'token',
        'auth_token',
        'secret_key',
        'private_key',
    ];
    
    /**
     * 处理请求
     */
    public function handle($request, Closure $next)
    {
        // 执行请求
        $response = $next($request);
        
        // 请求执行完后记录日志
        $this->recordBehaviorLog($request, $response);
        
        return $response;
    }
    
    /**
     * 记录操作日志
     */
    private function recordBehaviorLog($request, $response)
    {
        try {
            // 检查是否需要记录日志
            if (!$this->shouldRecord($request)) {
                return;
            }
            
            // 获取用户信息
            $userInfo = $request->userInfo ?? [];
            if (empty($userInfo)) {
                return; // 没有用户信息则不记录
            }
            
            // 获取控制器和方法名
            $controller = Request::controller();
            $action = Request::action();
            $behavior = $controller . '/' . $action;
            
            // 获取权限配置中的行为描述
            $permissions = config('permission.permissions');
            $behaviorText = '';
            if (isset($permissions[$controller]['actions'][$action])) {
                $behaviorText = $permissions[$controller]['module'] . '-' . $permissions[$controller]['actions'][$action];
            } else {
                $behaviorText = $behavior;
            }
            
            // 获取请求参数并过滤敏感信息
            $params = Request::param();
            foreach ($this->filterParams as $key) {
                if (isset($params[$key])) {
                    unset($params[$key]);
                }
            }
            
            // 判断操作状态（根据响应状态判断）
            $status = $this->getOperationStatus($response);
            
            // 构建日志数据
            $data = [
                'merchant_id' => $userInfo['merchant_id'] ?? 0,
                'user_id' => $userInfo['user_id'] ?? 0,
                'behavior' => $behaviorText,
                'behavior_desc' => json_encode($params, JSON_UNESCAPED_UNICODE),
                'behavior_ip' => getClientIp(),
                'behavior_url' => Request::pathinfo(),
                'behavior_status' => $status
            ];
            
            // 异步记录日志（避免影响响应性能）
            $this->asyncRecordLog($data);
            
        } catch (\Exception $e) {
            // 记录日志失败不影响业务
            // 可以在这里记录到错误日志中
        }
    }
    
    /**
     * 判断是否需要记录日志
     */
    private function shouldRecord($request): bool
    {
        // 只记录POST、PUT、DELETE请求
        $method = Request::method();
        if (!in_array($method, ['POST', 'PUT', 'DELETE', 'PATCH'])) {
            return false;
        }
        
        // 检查是否在排除列表中
        $controller = Request::controller();
        $action = Request::action();
        $currentAction = $controller . '/' . $action;
        
        if (in_array($currentAction, $this->excludeActions)) {
            return false;
        }
        
        // 检查权限配置中是否存在该操作
        $permissions = config('permission.permissions');
        if (!isset($permissions[$controller]['actions'][$action])) {
            return false; // 权限配置中不存在的操作不记录
        }
        
        return true;
    }
    
    /**
     * 根据响应判断操作状态
     */
    private function getOperationStatus($response): int
    {
        try {
            // 获取响应内容
            $content = $response->getContent();
            $data = json_decode($content, true);
            
            // 根据响应的code字段判断
            if (isset($data['code'])) {
                return $data['code'] == 200 ? UserBehaviorLogModel::STATUS_SUCCESS : UserBehaviorLogModel::STATUS_FAILED;
            }
            
            // 根据HTTP状态码判断
            $statusCode = $response->getCode();
            return $statusCode >= 200 && $statusCode < 300 ? UserBehaviorLogModel::STATUS_SUCCESS : UserBehaviorLogModel::STATUS_FAILED;
            
        } catch (\Exception $e) {
            // 默认为失败
            return UserBehaviorLogModel::STATUS_FAILED;
        }
    }
    
    /**
     * 异步记录日志
     */
    private function asyncRecordLog(array $data)
    {
        // 这里可以使用队列异步处理
        // 暂时直接记录
        UserBehaviorLogModel::recordBehavior($data);
    }
}