<?php

declare(strict_types=1);

namespace Kylin\Notification\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * 用户通知偏好模型
 *
 * 记录用户对各通知渠道的授权同意状态。
 *
 * 法律合规：
 *  - 依据《个人信息保护法》第四十四条，用户对个人信息处理享有知情权、决定权
 *  - 依据《通信短信息服务管理规定》第十八条，未经用户同意，不得发送商业性短信息
 *  - 依据《个人信息保护法》第四十七条，用户注销后应停止推送并清理设备信息
 */
class NotificationPreference extends Model
{
    protected $table = 'kylin_notification_preferences';

    protected $fillable = [
        'notifiable_type',
        'notifiable_id',
        'channel',
        'enabled',
        'consented_at',
        'revoked_at',
    ];

    protected $casts = [
        'enabled' => 'boolean',
        'consented_at' => 'datetime',
        'revoked_at' => 'datetime',
    ];

    /**
     * 用户授权同意某渠道
     */
    public static function grantConsent(string $notifiableType, int $notifiableId, string $channel): self
    {
        return static::updateOrCreate(
            [
                'notifiable_type' => $notifiableType,
                'notifiable_id' => $notifiableId,
                'channel' => $channel,
            ],
            [
                'enabled' => true,
                'consented_at' => now(),
                'revoked_at' => null,
            ]
        );
    }

    /**
     * 用户撤销某渠道授权
     */
    public static function revokeConsent(string $notifiableType, int $notifiableId, string $channel): void
    {
        static::where([
            'notifiable_type' => $notifiableType,
            'notifiable_id' => $notifiableId,
            'channel' => $channel,
        ])->update([
            'enabled' => false,
            'revoked_at' => now(),
        ]);
    }

    /**
     * 检查用户是否已授权某渠道
     *
     * 若无记录，则按默认策略（站内信默认允许，其他渠道默认拒绝）。
     */
    public static function isConsented(string $notifiableType, int $notifiableId, string $channel): bool
    {
        $pref = static::where([
            'notifiable_type' => $notifiableType,
            'notifiable_id' => $notifiableId,
            'channel' => $channel,
        ])->first();

        if ($pref) {
            return $pref->enabled && $pref->consented_at !== null && $pref->revoked_at === null;
        }

        // 默认策略：站内信默认允许，其他渠道（短信/推送/邮件）默认拒绝
        return $channel === 'database';
    }
}
