<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Tools\Support;

use App\Tools\ToolResult;

/**
 * 从入参/出参提取可审计的安全体积元数据。不保存完整 payload、提示词或密钥。
 */
final class ToolInvocationAuditMetadata
{
    /**
     * @var list<string>
     */
    private const REDACTED_KEYS = [
        'q',
        'keyword',
        'search',
        'remark',
        'prompt',
        'message',
        'name',
        'code',
    ];

    /**
     * @param  array<string, mixed>  $input
     * @return array{page: ?int, per_page: ?int, result_count: ?int, filter_fingerprint: ?string}
     */
    public static function from(array $input, ToolResult $result): array
    {
        return [
            'page' => self::positiveInt($input['page'] ?? null),
            'per_page' => self::positiveInt($input['per_page'] ?? null),
            'result_count' => self::resultCount($result),
            'filter_fingerprint' => self::fingerprint($input),
        ];
    }

    /**
     * @param  array<string, mixed>  $input
     */
    public static function fingerprint(array $input): ?string
    {
        if ($input === []) {
            return null;
        }

        $safe = [];

        foreach ($input as $key => $value) {
            if (! is_string($key) || $key === '') {
                continue;
            }

            if (in_array($key, self::REDACTED_KEYS, true)) {
                $safe[$key] = is_string($value) ? 'len:'.strlen($value) : 'present';

                continue;
            }

            if (is_int($value) || is_float($value) || is_bool($value) || $value === null) {
                $safe[$key] = $value;

                continue;
            }

            if (is_string($value)) {
                $safe[$key] = ToolBusinessDate::isValid($value) || strlen($value) <= 32
                    ? $value
                    : 'len:'.strlen($value);
            }
        }

        ksort($safe);

        return hash('sha256', (string) json_encode($safe, JSON_UNESCAPED_UNICODE));
    }

    private static function resultCount(ToolResult $result): ?int
    {
        if (! $result->success || ! is_array($result->data)) {
            return 0;
        }

        foreach (['items', 'counterparties', 'rows'] as $key) {
            if (isset($result->data[$key]) && is_array($result->data[$key])) {
                return count($result->data[$key]);
            }
        }

        return 1;
    }

    private static function positiveInt(mixed $value): ?int
    {
        if (! is_numeric($value)) {
            return null;
        }

        $int = (int) $value;

        return $int > 0 ? $int : null;
    }
}
