<?php
// +----------------------------------------------------------------------
// | onezan-admin 快速开发的管理平台
// +----------------------------------------------------------------------
// | 官方网址：https://www.onezan.cn
// +----------------------------------------------------------------------
// | onezan团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: 543885307@qq.com
// +----------------------------------------------------------------------
namespace app\service\domain\user;

use app\repository\user\UserRepository;
use app\service\InputHelper;
use Core\service\BaseCoreService;
use think\facade\Db;

/**
 * 用户余额服务
 * @package app\service\domain\user
 * Class CoreUserBalanceService
 * @package app\service\domain\user
 */
class CoreUserBalanceService extends BaseCoreService
{
    /**
     * 调整用户余额
     * @param int $userId 用户ID
     * @param string $action 操作类型
     * @param string $amountRaw 金额原始字符串
     * @param string $bizType 业务类型
     * @param string $remark 备注
     * @param int $adminUid 管理员ID
     * @return array
     */
    public function adjust(int $userId, string $action, string $amountRaw, string $bizType, string $remark, int $adminUid): array
    {
        if (!in_array($action, ['recharge', 'deduct'], true)) {
            return ['code' => 1, 'msg' => ''];
        }
        if ($amountRaw === '' || !is_numeric($amountRaw)) {
            return ['code' => 1, 'msg' => ''];
        }

        $amount = InputHelper::normalizeDecimalString($amountRaw, 4);
        if (InputHelper::decimalCmp($amount, '0', 4) <= 0) {
            return ['code' => 1, 'msg' => '0'];
        }

        Db::startTrans();
        try {
            $user = $this->userRepository()->lockById($userId);
            if (!$user) {
                Db::rollback();
                return ['code' => 1, 'msg' => ''];
            }

            $before = InputHelper::normalizeDecimalString($user->balance ?? '0', 4);
            $delta = $amount;
            $transactionType = 'money_in';
            if ($action === 'deduct') {
                if (InputHelper::decimalCmp($before, $amount, 4) < 0) {
                    Db::rollback();
                    return ['code' => 1, 'msg' => ''];
                }
                $delta = InputHelper::decimalAdd('0', '-' . $amount, 4);
                $transactionType = 'money_out';
            }

            $after = InputHelper::decimalAdd($before, $delta, 4);
            $user->balance = (float)$after;
            $user->save();

            $actionText = $action === 'recharge' ? 'Recharge' : 'Deduct';
            $remarkText = '' . $actionText . '[' . mb_substr($bizType === '' ? 'manual' : $bizType, 0, 20) . ']';
            if ($remark !== '') {
                $remarkText .= ' ' . mb_substr($remark, 0, 120);
            }

            $now = time();
            Db::name('sys_user_balance_logs')->insert([
                'user_id' => $userId,
                'type' => $transactionType,
                'amount' => (float)$delta,
                'balance' => (float)$after,
                'biz_type' => $bizType,
                'biz_id' => '',
                'remark' => $remarkText,
                'operator' => (string)($adminUid > 0 ? $adminUid : 0),
                'create_time' => $now,
                'update_time' => $now,
            ]);

            Db::commit();
            return [
                'code' => 0,
                'msg' => '',
                'data' => [
                    'user_id' => $userId,
                    'balance_before' => $before,
                    'balance_after' => $after,
                ],
            ];
        } catch (\Throwable $e) {
            Db::rollback();
            return ['code' => 1, 'msg' => ''];
        }
    }

    /**
     * 获取用户余额仓库
     * @return UserRepository
     */
    private function userRepository(): UserRepository
    {
        return $this->app->make(UserRepository::class);
    }
}