<?php

namespace App\Services\Agent;

use App\Models\AgentNode;
use App\Models\AgentProfile;
use App\Support\PlayerFundingMode;
use Illuminate\Support\Facades\DB;

/**
 * 按「下发即占用」真理源重算代理已下发额度：
 * 直属玩家 credit_limit 之和 + 直属下级代理 credit_limit 之和。
 */
final class AgentCreditAllocatedSyncService
{
    public function syncForAgent(AgentNode $agent): void
    {
        $profile = AgentProfile::query()->where('agent_node_id', $agent->id)->first();
        if ($profile === null) {
            return;
        }

        $expected = $this->calculateAllocatedCredit($agent);
        if ((int) $profile->allocated_credit === $expected) {
            return;
        }

        $profile->allocated_credit = $expected;
        $profile->save();
    }

    public function syncForAgentId(int $agentNodeId): void
    {
        $agent = AgentNode::query()->find($agentNodeId);
        if ($agent === null) {
            return;
        }

        $this->syncForAgent($agent);
    }

    public function calculateAllocatedCredit(AgentNode $agent): int
    {
        $playerTotal = (int) DB::table('player_credit_accounts as pca')
            ->join('players as p', 'p.id', '=', 'pca.player_id')
            ->where('p.agent_node_id', $agent->id)
            ->where('p.funding_mode', PlayerFundingMode::CREDIT)
            ->sum('pca.credit_limit');

        $childIds = AgentNode::query()->where('parent_id', $agent->id)->pluck('id');
        $childAgentTotal = $childIds->isEmpty()
            ? 0
            : (int) AgentProfile::query()->whereIn('agent_node_id', $childIds)->sum('credit_limit');

        return $playerTotal + $childAgentTotal;
    }
}
