<?php

namespace App\Services\Settlement\Matchers;

use App\Models\TicketItem;
use App\Models\TicketCombination;
use Illuminate\Support\Collection;
use App\Services\Settlement\OddsSnapshotReader;
use App\Services\Settlement\PublishedDrawResultBoard;
use App\Services\Settlement\Contracts\SettlementPlayMatcher;

/** Settles aggregate 4D / suffix plays against an explicit group of prize scopes. */
final class ScopeFilteredSettlementMatcher implements SettlementPlayMatcher
{
    /** @var array<string, list<string>> */
    private const SCOPES = [
        'four_lower' => ['starter', 'consolation'],
        'pos_3lower' => ['starter', 'consolation'],
        'pos_2any' => ['first', 'second', 'third', 'starter', 'consolation'],
    ];

    public function __construct(private readonly OddsSnapshotReader $odds) {}

    public function match(TicketItem $item, PublishedDrawResultBoard $board, Collection $combinations): array
    {
        $allowed = self::SCOPES[(string) $item->play_code] ?? [];
        $snapshot = is_array($item->odds_snapshot_json) ? $item->odds_snapshot_json : null;
        $lines = [];
        $total = 0;
        $bestTier = null;

        foreach ($combinations as $combo) {
            /** @var TicketCombination $combo */
            $hit = $board->bestTierForNumber((string) $combo->number_4d);
            if ($hit === null || ! in_array($hit['tier'], $allowed, true)) continue;
            $oddsValue = $this->odds->oddsValueForScope($snapshot, $hit['tier']);
            $payout = (int) floor((int) $combo->bet_amount * ($oddsValue / 10_000));
            $total += $payout;
            $bestTier ??= $hit['tier'];
            $lines[] = ['number_4d' => $combo->number_4d, 'tier' => $hit['tier'], 'payout' => $payout];
        }

        return ['win_amount' => $total, 'matched_prize_tier' => $bestTier, 'match_detail' => ['lines' => $lines]];
    }
}
