<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;

function Mirai_referralGetWithdrawableRebate($uid) {
    $db = \Typecho\Db::get();
    $orderTable = Mirai_pointsTable('mirai_pay_orders');
    $row = $db->fetchRow($db->select(['SUM(rebate_price)' => 'total'])->from($orderTable)
        ->where('referrer_uid = ? AND rebate_status = ? AND rebate_price > 0 AND status = ?', $uid, 0, 'paid'));
    return (float)($row['total'] ?? 0);
}

function Mirai_referralApplyWithdraw($uid, $amount = 0, $accountType = '', $accountName = '', $accountNo = '', $qrCodeUrl = '') {
    if (!$uid) return ['success' => false, 'msg' => '请先登录'];
    if (!Mirai_referralIsEnabled()) return ['success' => false, 'msg' => '推广返佣未启用'];

    $options = Mirai_opt();
    $minAmount = isset($options->referralWithdrawMin) ? (float)$options->referralWithdrawMin : 50;

    $withdrawable = Mirai_referralGetWithdrawableRebate($uid);
    if ($withdrawable <= 0) return ['success' => false, 'msg' => '没有可提现的佣金'];

    if ($amount <= 0) $amount = $withdrawable;
    if ($amount < $minAmount) return ['success' => false, 'msg' => '最低提现金额' . $minAmount . '元'];
    if ($amount > $withdrawable) $amount = $withdrawable;

    $db = \Typecho\Db::get();
    $orderTable = Mirai_pointsTable('mirai_pay_orders');
    $withdrawTable = Mirai_pointsTable('mirai_pay_withdrawals');

    $lockKey = 'mirai_rebate_withdraw_' . $uid;
    if (!Mirai_payAcquireLock($lockKey, 10)) {
        return ['success' => false, 'msg' => '系统繁忙，请稍后再试'];
    }

    try {
        $db->query('BEGIN');

        $existingPending = $db->fetchRow($db->select('id')->from($withdrawTable)
            ->where('uid = ?', $uid)->where('status = ?', 0)->where('withdraw_type = ?', 'rebate')->limit(1));
        if ($existingPending) {
            $db->query('ROLLBACK');
            Mirai_payReleaseLock($lockKey);
            return ['success' => false, 'msg' => '您有佣金提现申请正在处理中，请等待处理完成'];
        }

        $feeRate = isset($options->referralWithdrawFee) ? (float)$options->referralWithdrawFee : 0;
        $fee = round($amount * $feeRate / 100, 2);
        $actualAmount = round($amount - $fee, 2);

        $orders = $db->fetchAll($db->select('id', 'rebate_price')->from($orderTable)
            ->where('referrer_uid = ? AND rebate_status = ? AND rebate_price > 0 AND status = ?', $uid, 0, 'paid')
            ->order('id', \Typecho\Db::SORT_ASC));

        if (empty($orders)) {
            $db->query('ROLLBACK');
            Mirai_payReleaseLock($lockKey);
            return ['success' => false, 'msg' => '没有可提现的佣金订单'];
        }

        $orderIds = [];
        $accumulated = 0;
        foreach ($orders as $o) {
            $orderIds[] = (int)$o['id'];
            $accumulated += (float)$o['rebate_price'];
            if ($accumulated >= $amount) break;
        }

        $idList = implode(',', $orderIds);
        $db->query($db->update($orderTable)->rows(['rebate_status' => 2])
            ->where('referrer_uid = ? AND rebate_status = ? AND rebate_price > 0 AND status = ?', $uid, 0, 'paid')
            ->where('id IN (' . $idList . ')'));

        $db->query($db->insert($withdrawTable)->rows([
            'uid' => $uid,
            'amount' => $amount,
            'withdraw_type' => 'rebate',
            'status' => 0,
            'account_type' => $accountType,
            'account_name' => $accountName,
            'account_no' => $accountNo,
            'qr_code' => $qrCodeUrl,
            'remark' => '佣金提现，手续费' . $fee . '元，实际到账' . $actualAmount . '元',
            'admin_remark' => '',
            'created' => time(),
            'processed_at' => 0,
        ]));

        $withdrawId = $db->lastInsertId();

        $detail = json_encode([
            'withdraw_id' => $withdrawId,
            'order_ids' => $orderIds,
            'created' => time()
        ], JSON_UNESCAPED_UNICODE);
        $db->query($db->update($orderTable)->rows(['rebate_detail' => $detail])
            ->where('id IN (' . $idList . ')'));

        $db->query('COMMIT');
        Mirai_payReleaseLock($lockKey);
        return ['success' => true, 'amount' => $amount, 'fee' => $fee, 'actual' => $actualAmount, 'withdraw_id' => $withdrawId];
    } catch (\Exception $e) {
        $db->query('ROLLBACK');
        Mirai_payReleaseLock($lockKey);
        return ['success' => false, 'msg' => '申请失败: ' . $e->getMessage()];
    }
}

function Mirai_referralProcessWithdraw($withdrawId, $approved, $adminRemark = '') {
    $db = \Typecho\Db::get();
    $withdrawTable = Mirai_pointsTable('mirai_pay_withdrawals');
    $orderTable = Mirai_pointsTable('mirai_pay_orders');

    $withdraw = $db->fetchRow($db->select()->from($withdrawTable)->where('id = ?', $withdrawId));
    if (!$withdraw) return false;

    $uid = (int)$withdraw['uid'];
    $lockKey = 'mirai_rebate_withdraw_' . $uid;
    if (!Mirai_payAcquireLock($lockKey, 10)) {
        return false;
    }

    try {
        $db->query('BEGIN');

        $withdraw = $db->fetchRow($db->select()->from($withdrawTable)->where('id = ?', $withdrawId)->where('status = ?', 0));
        if (!$withdraw) {
            $db->query('ROLLBACK');
            Mirai_payReleaseLock($lockKey);
            return false;
        }

        $newStatus = $approved ? 1 : 2;

        $updateResult = $db->query($db->update($withdrawTable)->rows([
            'status' => $newStatus,
            'admin_remark' => $adminRemark,
            'processed_at' => time(),
        ])->where('id = ?', $withdrawId)->where('status = ?', 0));

        if (!$updateResult) {
            $db->query('ROLLBACK');
            Mirai_payReleaseLock($lockKey);
            return false;
        }

        $rebateStatus = $approved ? 1 : 0;

        $orders = $db->fetchAll($db->select('id', 'rebate_detail')->from($orderTable)
            ->where('referrer_uid = ? AND rebate_status = ?', $uid, 2));
        if (!empty($orders)) {
            $orderIds = [];
            foreach ($orders as $o) {
                $detailJson = isset($o['rebate_detail']) ? $o['rebate_detail'] : '';
                $detailData = $detailJson ? json_decode($detailJson, true) : [];
                if (isset($detailData['withdraw_id']) && (int)$detailData['withdraw_id'] === (int)$withdrawId) {
                    $orderIds[] = (int)$o['id'];
                }
            }
            if (!empty($orderIds)) {
                $idList = implode(',', $orderIds);
                $db->query($db->update($orderTable)->rows(['rebate_status' => $rebateStatus])
                    ->where('referrer_uid = ? AND rebate_status = ?', $uid, 2)
                    ->where('id IN (' . $idList . ')'));
            }
        }

        $db->query('COMMIT');
        Mirai_payReleaseLock($lockKey);
        return true;
    } catch (\Exception $e) {
        $db->query('ROLLBACK');
        Mirai_payReleaseLock($lockKey);
        return false;
    }
}
