<?php

namespace App\Support;

use App\Models\AdminUser;
use App\Models\TransferOrder;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Http\Request;

/**
 * 统一后台数据范围策略：站点优先 + 代理子树收敛。
 */
final class AdminScopePolicy
{
    public static function resolveContext(
        Request $request,
        AdminUser $admin,
        string $siteParam = 'site_code',
        string $agentParam = 'agent_node_id',
    ): AdminScopeContext {
        return AdminScopeContextResolver::fromRequest($request, $admin, $siteParam, $agentParam);
    }

    /**
     * @param  EloquentBuilder<mixed>  $query
     */
    public static function applyViaPlayer(
        EloquentBuilder $query,
        AdminUser|AdminScopeContext $scope,
        string $relation = 'player',
    ): void {
        $context = self::normalizeContext($scope);
        AdminSiteScope::applyViaPlayerRelation($query, $context->admin, $relation);
    }

    /**
     * @param  EloquentBuilder<\App\Models\Player>  $query
     */
    public static function applyPlayerFilters(EloquentBuilder $query, AdminScopeContext $context): void
    {
        AdminSiteScope::applyPlayerFilters(
            $query,
            $context->admin,
            $context->effectiveRequestedSiteCode(),
            $context->effectiveRequestedAgentNodeId(),
        );
    }

    /**
     * @param  EloquentBuilder<mixed>  $query
     */
    public static function applyViaPlayerRelationWithContext(
        EloquentBuilder $query,
        AdminScopeContext $context,
        string $relation = 'player',
    ): void {
        AdminSiteScope::applyViaPlayerRelationWithSiteCode(
            $query,
            $context->admin,
            $context->effectiveRequestedSiteCode(),
            $relation,
            $context->effectiveRequestedAgentNodeId(),
        );
    }

    /**
     * @param  QueryBuilder<mixed>  $query
     */
    public static function applyPlayersAlias(
        QueryBuilder $query,
        AdminUser|AdminScopeContext $scope,
        string $alias = 'p',
    ): void {
        $context = self::normalizeContext($scope);
        AdminDataScope::applyToPlayersAlias(
            $query,
            $context->admin,
            $alias,
            $context->effectiveRequestedAgentNodeId(),
        );
    }

    /**
     * @param  QueryBuilder<mixed>  $query
     */
    public static function applyTicketOrdersViaPlayer(
        QueryBuilder $query,
        AdminUser|AdminScopeContext $scope,
        string $orderAlias = 'o',
    ): void {
        $context = self::normalizeContext($scope);
        AdminDataScope::applyToTicketOrdersViaPlayer($query, $context->admin, $orderAlias);
    }

    public static function transferOrderAccessible(AdminUser|AdminScopeContext $scope, TransferOrder $order): bool
    {
        $context = self::normalizeContext($scope);
        $player = $order->player;
        if ($player === null) {
            return false;
        }

        return AdminSiteScope::playerAccessible($context->admin, $player);
    }

    private static function normalizeContext(AdminUser|AdminScopeContext $scope): AdminScopeContext
    {
        if ($scope instanceof AdminScopeContext) {
            return $scope;
        }

        return AdminScopeContextResolver::fromValues($scope);
    }
}
