<?php

declare(strict_types=1);

namespace Kylin\RiskControl\Services;

use Illuminate\Support\Facades\Log;

/**
 * 大额交易报告服务
 *
 * 依据《金融机构大额交易和可疑交易报告管理办法》：
 *  - 大额转账：单笔 >= 50,000 元
 *  - 大额现金：单笔 >= 200,000 元
 *
 * 使用方式：
 *   $report = LargeTransactionReport::generate($transaction);
 *   $report = LargeTransactionReport::shouldReport($amount, $type);
 */
final class LargeTransactionReport
{
    /** 大额转账阈值 */
    public const LARGE_TRANSFER = 50_000;

    /** 大额现金阈值 */
    public const LARGE_CASH = 200_000;

    /**
     * 判断是否需要报告大额交易
     *
     * @param float  $amount 交易金额
     * @param string $type   交易类型（transfer/cash）
     * @return bool
     */
    public static function shouldReport(float $amount, string $type = 'transfer'): bool
    {
        return match ($type) {
            'transfer' => $amount >= self::LARGE_TRANSFER,
            'cash' => $amount >= self::LARGE_CASH,
            default => false,
        };
    }

    /**
     * 生成大额交易报告
     *
     * @param array{ amount: float, type: string, user_id: int, user_name: string, transaction_id: string, created_at: string } $transaction
     * @return array<string, mixed>
     */
    public static function generate(array $transaction): array
    {
        if (! self::shouldReport($transaction['amount'], $transaction['type'] ?? 'transfer')) {
            return [
                'reportable' => false,
                'reason' => '金额未达大额交易报告阈值',
            ];
        }

        $report = [
            'reportable' => true,
            'report_type' => 'large_transaction',
            'transaction_id' => $transaction['transaction_id'] ?? '',
            'amount' => $transaction['amount'],
            'type' => $transaction['type'] ?? 'transfer',
            'user_id' => $transaction['user_id'] ?? 0,
            'user_name' => $transaction['user_name'] ?? '',
            'threshold' => $transaction['type'] === 'cash' ? self::LARGE_CASH : self::LARGE_TRANSFER,
            'reported_at' => now()->toDateTimeString(),
            'status' => 'pending_review',
            'law' => '《金融机构大额交易和可疑交易报告管理办法》',
        ];

        self::audit('large_transaction_reported', $transaction['user_id'] ?? 0, [
            'transaction_id' => $report['transaction_id'],
            'amount' => $report['amount'],
            'type' => $report['type'],
            'threshold' => $report['threshold'],
        ]);

        return $report;
    }

    /**
     * 获取大额交易报告阈值
     *
     * @return array{ transfer: int, cash: int }
     */
    public static function thresholds(): array
    {
        return [
            'transfer' => self::LARGE_TRANSFER,
            'cash' => self::LARGE_CASH,
        ];
    }

    /**
     * 记录大额交易审计日志
     *
     * 依据《反洗钱法》和《金融机构大额交易和可疑交易报告管理办法》，
     * 大额交易报告生成需记录审计日志，便于反洗钱合规审计。
     */
    private static function audit(string $event, int $userId, array $extra = []): void
    {
        if (! class_exists(\Kylin\AuditLog\Models\AuditLog::class)) {
            return;
        }

        try {
            \Kylin\AuditLog\Models\AuditLog::create([
                'event' => $event,
                'model_type' => 'transaction',
                'model_id' => $userId,
                'new_values' => $extra,
                'old_values' => null,
                'user_id' => auth()->id(),
                'ip' => request()?->ip(),
                'url' => request()?->fullUrl(),
                'tag' => 'risk-control-large-tx',
            ]);
        } catch (\Throwable $e) {
            Log::warning('大额交易审计日志写入失败', [
                'error' => $e->getMessage(),
                'user_id' => $userId,
                'event' => $event,
            ]);
        }
    }
}