<?php

namespace App\Services\Admin;

use App\Models\AdminUser;
use App\Models\Player;
use App\Models\TransferOrder;
use App\Support\AdminAgentScope;
use App\Support\AdminDataScope;
use App\Support\AdminScopeContext;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;

/** 站点财务仪表盘：对账异常、待确认/待收付账单、钱包玩家规模。 */
final class SiteFinanceDashboardOverviewBuilder
{
    /**
     * @return array<string, mixed>|null
     */
    public function build(AdminUser $admin, AdminScopeContext $scope): ?array
    {
        if (! $admin->hasPermissionCode('dashboard.view')) {
            return null;
        }

        $site = SiteDashboardSiteResolver::resolvePrimarySite($admin);
        if ($site === null) {
            return null;
        }

        $siteId = (int) $site->id;
        $siteCode = (string) $site->code;
        $billStats = SiteSettlementBillStats::forSite($siteId);
        $currencyCode = Player::query()
            ->where('site_code', $siteCode)
            ->whereNotNull('default_currency')
            ->value('default_currency');

        return [
            'admin_site_id' => $siteId,
            'site_code' => $siteCode,
            'site_name' => (string) $site->name,
            'wallet_player_count' => (int) Player::query()
                ->where('site_code', $siteCode)
                ->where('funding_mode', 'wallet')
                ->count(),
            'credit_player_count' => (int) Player::query()
                ->where('site_code', $siteCode)
                ->where('funding_mode', 'credit')
                ->count(),
            'pending_confirm_bill_count' => $billStats['pending_confirm_count'],
            'payable_bill_count' => $billStats['payable_count'],
            'payable_unpaid_minor' => $billStats['payable_unpaid_minor'],
            'pending_bill_count' => $billStats['pending_confirm_count'] + $billStats['payable_count'],
            'pending_unpaid_minor' => $billStats['payable_unpaid_minor'],
            'abnormal_transfer_count' => $this->abnormalTransferCount($admin, $scope),
            'currency_code' => is_string($currencyCode) && $currencyCode !== '' ? $currencyCode : null,
        ];
    }

    private function abnormalTransferCount(AdminUser $admin, AdminScopeContext $scope): int
    {
        $query = TransferOrder::query()
            ->whereIn('status', ['processing', 'failed', 'pending_reconcile']);
        AdminDataScope::applyEloquentViaPlayer($query, $admin);
        $this->applyRequestedScopeViaPlayer($query, $scope);

        return (int) $query->count();
    }

    /**
     * @param EloquentBuilder<mixed> $query
     */
    private function applyRequestedScopeViaPlayer(EloquentBuilder $query, AdminScopeContext $scope): void
    {
        $siteCode = $scope->effectiveRequestedSiteCode();
        $agentNodeId = $scope->effectiveRequestedAgentNodeId();
        if ($siteCode === null && $agentNodeId === null) {
            return;
        }

        $admin = $scope->admin;
        $query->whereHas('player', static function (EloquentBuilder $playerQuery) use ($admin, $siteCode, $agentNodeId): void {
            if ($siteCode !== null) {
                $playerQuery->where('site_code', $siteCode);
            }

            if ($agentNodeId !== null) {
                AdminAgentScope::applyRequestedAgentNodeFilter($playerQuery, $admin, $agentNodeId);
            }
        });
    }
}
