<?php

declare(strict_types=1);

namespace app\admin\model;

use app\common\model\MallUserAsset;
use think\model\relation\BelongsTo;

class MallPointsLog extends \app\common\model\MallPointsLog
{
    public static function onBeforeInsert($model): void
    {
        $userAssetId = filter_var($model->user_asset_id, FILTER_VALIDATE_INT);
        if ($userAssetId === false || $userAssetId <= 0) {
            throw new \InvalidArgumentException(__('User asset not found'));
        }

        $scoreValue = filter_var($model->score_value, FILTER_VALIDATE_INT);
        if ($scoreValue === false || $scoreValue === 0) {
            throw new \InvalidArgumentException(__('Points adjustment must be a non-zero integer'));
        }

        $userAsset = MallUserAsset::where('id', $userAssetId)->lock(true)->find();
        if (!$userAsset) {
            throw new \RuntimeException(__('User asset not found'));
        }

        $before = $userAsset->available_points;
        $after = $before + $scoreValue;
        if ($after < 0) {
            throw new \RuntimeException(__('Insufficient available points'));
        }

        $model->user_asset_id = $userAssetId;
        $model->score_value = $scoreValue;
        $model->before = $before;
        $model->after = $after;
        $model->memo = $scoreValue > 0
            ? __('Administrator added %s points', [abs($scoreValue)])
            : __('Administrator deducted %s points', [abs($scoreValue)]);

        $userAsset->available_points = $after;
        $userAsset->save();
    }

    public static function onBeforeDelete(): bool
    {
        return false;
    }

    public function userAsset(): BelongsTo
    {
        return $this->belongsTo(MallUserAsset::class, 'user_asset_id');
    }

    public function admin(): BelongsTo
    {
        return $this->belongsTo(Admin::class, 'admin_id');
    }
}
