<?php

namespace App\Services\Admin;

use App\Models\AdminUser;
use App\Services\AgentSettlement\ShareLedgerScopedProfitAggregator;
use App\Support\AdminScopeContextResolver;

/**
 * 仪表盘可筛选分析数据：区间汇总、日趋势、玩法拆解。
 */
final class AdminDashboardAnalyticsBuilder
{
    public function __construct(
        private readonly AdminReportQueryService $reportQuery,
        private readonly ShareLedgerScopedProfitAggregator $shareProfitAggregator,
    ) {}

    /**
     * @param array{
     *     period?: string,
     *     date_from?: string|null,
     *     date_to?: string|null,
     *     metric?: string,
     *     play_code?: string|null
     * } $filters
     *
     * @return array<string, mixed>|null
     */
    public function build(AdminUser $admin, array $filters): ?array
    {
        if (! $this->canView($admin)) {
            return null;
        }

        $scope = AdminScopeContextResolver::fromValues(
            $admin,
            requestedSiteCode: isset($filters['site_code']) ? (string) $filters['site_code'] : null,
            requestedAgentNodeId: isset($filters['agent_node_id']) ? (int) $filters['agent_node_id'] : null,
        );

        $period = (string) ($filters['period'] ?? 'last_7_days');
        $metric = (string) ($filters['metric'] ?? 'overview');
        $playCode = isset($filters['play_code']) && $filters['play_code'] !== ''
            ? (string) $filters['play_code']
            : null;

        $range = $this->reportQuery->resolveDashboardPeriod(
            $period,
            isset($filters['date_from']) ? (string) $filters['date_from'] : null,
            isset($filters['date_to']) ? (string) $filters['date_to'] : null,
        );

        $dateFrom = $range['date_from'];
        $dateTo = $range['date_to'];

        $trend = $this->reportQuery->dailyProfitSeriesFilled($dateFrom, $dateTo, scope: $scope);
        $summary = $this->reportQuery->periodFinanceTotals($dateFrom, $dateTo, $scope);
        $dailySeries = $trend['series'];
        $profitScope = 'house_gross';

        if ($admin->primaryAgentNode() !== null) {
            $profitScope = 'share_profit';
            $shareByDate = $this->shareProfitAggregator->shareProfitByBusinessDate($admin, $dateFrom, $dateTo);
            $summary['approx_house_gross_minor'] = $this->shareProfitAggregator->sumShareProfitForAdmin(
                $admin,
                $dateFrom,
                $dateTo,
            );
            $dailySeries = array_map(
                static function (array $row) use ($shareByDate): array {
                    $row['approx_house_gross_minor'] = $shareByDate[(string) $row['business_date']] ?? 0;

                    return $row;
                },
                $dailySeries,
            );
        }

        return [
            'period' => $period,
            'metric' => $metric,
            'play_code' => $playCode,
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'profit_scope' => $profitScope,
            'currency_code' => $this->reportQuery->resolvePeriodCurrencyCode($dateFrom, $dateTo, $scope),
            'summary' => $summary,
            'daily_series' => $dailySeries,
            'chart_meta' => [
                'chart_date_from' => $trend['chart_date_from'],
                'chart_date_to' => $trend['chart_date_to'],
                'truncated' => $trend['truncated'],
                'span_days' => $trend['span_days'],
            ],
            'play_breakdown' => $this->reportQuery->playDimensionBreakdownRows(
                $dateFrom,
                $dateTo,
                $playCode,
                scope: $scope,
            ),
            'agent_breakdown' => $this->reportQuery->agentRankingRows(
                $dateFrom,
                $dateTo,
                $playCode,
                limit: 200,
                scope: $scope,
            ),
        ];
    }

    /** 与 {@see AdminAuthorizationRegistry} 中 dashboard 类 API 资源的 `dashboard.view` 绑定一致。 */
    private function canView(AdminUser $admin): bool
    {
        return $admin->hasPermissionCode('dashboard.view');
    }
}
