<?php

declare(strict_types=1);

namespace Kylin\RiskEngine\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * 风控黑白名单模型
 *
 * 支持 IP、设备指纹、用户 ID、手机号等多维度黑白名单管理。
 * 命中黑名单直接拒绝（lockout），白名单直接放行（pass）。
 *
 * 依据《未成年人保护法》第七十五条，需建立风控机制。
 * 依据等保 2.0 (GB/T 22239)，访问控制需记录审计日志。
 *
 * @property int    $id
 * @property string $list_type    名单类型：blacklist / whitelist
 * @property string $target_type  目标类型：user / ip / device / phone / fingerprint
 * @property string $target_value 目标值
 * @property string $reason       加入原因
 * @property string $expire_at    过期时间
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 */
class BlackWhiteList extends Model
{
    protected $table = 'kylin_risk_black_white_list';

    protected $fillable = [
        'list_type',
        'target_type',
        'target_value',
        'reason',
        'expire_at',
    ];

    protected $casts = [
        'expire_at' => 'datetime',
    ];

    /**
     * 检查是否在黑名单中
     */
    public static function isBlacklisted(string $targetType, string $targetValue): bool
    {
        return static::where('list_type', 'blacklist')
            ->where('target_type', $targetType)
            ->where('target_value', $targetValue)
            ->where(function ($query) {
                $query->whereNull('expire_at')
                    ->orWhere('expire_at', '>', now());
            })
            ->exists();
    }

    /**
     * 检查是否在白名单中
     */
    public static function isWhitelisted(string $targetType, string $targetValue): bool
    {
        return static::where('list_type', 'whitelist')
            ->where('target_type', $targetType)
            ->where('target_value', $targetValue)
            ->where(function ($query) {
                $query->whereNull('expire_at')
                    ->orWhere('expire_at', '>', now());
            })
            ->exists();
    }

    /**
     * 添加到黑名单
     */
    public static function addToBlacklist(string $targetType, string $targetValue, string $reason, ?\DateTimeInterface $expireAt = null): self
    {
        return static::create([
            'list_type'    => 'blacklist',
            'target_type'  => $targetType,
            'target_value' => $targetValue,
            'reason'       => $reason,
            'expire_at'    => $expireAt,
        ]);
    }

    /**
     * 添加到白名单
     */
    public static function addToWhitelist(string $targetType, string $targetValue, string $reason, ?\DateTimeInterface $expireAt = null): self
    {
        return static::create([
            'list_type'    => 'whitelist',
            'target_type'  => $targetType,
            'target_value' => $targetValue,
            'reason'       => $reason,
            'expire_at'    => $expireAt,
        ]);
    }

    /**
     * 从名单中移除
     */
    public static function remove(string $targetType, string $targetValue): int
    {
        return static::where('target_type', $targetType)
            ->where('target_value', $targetValue)
            ->delete();
    }

    /**
     * 检查是否过期
     */
    public function isExpired(): bool
    {
        return $this->expire_at !== null && now()->gt($this->expire_at);
    }
}