<?php

declare(strict_types=1);

namespace App\Service;

use App\Model\OperationLog;
use App\Model\User;
use App\Utils\Log;
use Qbhy\HyperfAuth\AuthManager;
use Swoole\Coroutine;

class OperationLogService
{
    /**
     * 记录操作日志（异步写库，不阻塞业务）
     */
    public static function log(
        int $user_id,
        string $action,
        string $target_type,
        ?int $target_id,
        string $description,
        ?array $detail = null,
        ?string $ip = null,
    ): void {
        Coroutine::defer(static function () use (
            $user_id, $action, $target_type, $target_id, $description, $detail, $ip
        ): void {
            try {
                OperationLog::query()->create([
                    'user_id' => $user_id,
                    'action' => $action,
                    'target_type' => $target_type,
                    'target_id' => $target_id,
                    'description' => $description,
                    'detail' => $detail,
                    'ip' => $ip,
                ]);
            } catch (\Throwable $e) {
                Log::get()->error('OperationLogService: 写入操作日志失败', [
                    'error' => $e->getMessage(),
                    'action' => $action,
                ]);
            }
        });
    }

    /**
     * 从当前认证上下文获取用户 ID
     *
     * 优先从 request attribute 获取（兼容 API Key 认证），再 fallback 到 JWT guard
     */
    public static function getCurrentUserId(): ?int
    {
        try {
            // 优先从 request context 获取（API Key 认证存储在 auth_user attribute）
            $request = \Hyperf\Context\Context::get(\Psr\Http\Message\ServerRequestInterface::class);
            if ($request) {
                $user = $request->getAttribute('auth_user');
                if ($user instanceof User) {
                    return $user->id;
                }
            }

            // Fallback: JWT guard
            $container = \Hyperf\Context\ApplicationContext::getContainer();
            $auth = $container->get(AuthManager::class);
            $user = $auth->guard('jwt')->user();
            if ($user instanceof User) {
                return $user->id;
            }
            return $user?->getId();
        } catch (\Throwable $e) {
            Log::get()->warning('OperationLogService: 获取当前用户 ID 失败', [
                'error' => $e->getMessage(),
            ]);
            return null;
        }
    }
}
