<?php

namespace App\Http\Controllers;

use App\Models\Tournament;
use App\Models\TournamentParticipant;
use App\Services\TournamentBracketService;
use Illuminate\Http\JsonResponse;

class TournamentController extends Controller
{
    public function __construct(private TournamentBracketService $bracket) {}

    public function index()
    {
        $tournaments = Tournament::withCount('participants')
            ->orderByDesc('created_at')
            ->paginate(12);

        return view('tournament.index', compact('tournaments'));
    }

    public function show(int $id)
    {
        $tournament = Tournament::withCount('participants')
            ->with(['participants.user', 'creator'])
            ->findOrFail($id);

        $groupData    = [];
        $knockoutData = [];

        // Show bracket whenever matches exist (not just in_progress/completed)
        $hasMatches = $tournament->tournamentMatches()->exists();

        if ($hasMatches || in_array($tournament->status, ['in_progress', 'completed'])) {
            if ($tournament->format === 'group_knockout') {
                $groupData = $this->bracket->getGroupStandings($tournament);
            }
            $knockoutData = $this->bracket->getKnockoutBracket($tournament);
        }

        return view('tournament.show', compact('tournament', 'groupData', 'knockoutData'));
    }

    public function register(int $id)
    {
        $tournament = Tournament::findOrFail($id);
        abort_unless($tournament->isRegistrationOpen(), 422, 'Registrasi sudah ditutup.');

        TournamentParticipant::firstOrCreate([
            'tournament_id' => $tournament->id,
            'user_id'       => auth()->id(),
        ]);

        return back()->with('success', 'Berhasil mendaftar turnamen!');
    }

    /**
     * Live JSON endpoint — polled every N seconds by frontend.
     */
    public function live(int $id): JsonResponse
    {
        $tournament = Tournament::findOrFail($id);

        $groupData    = [];
        $knockoutData = [];

        if ($tournament->format === 'group_knockout') {
            $raw = $this->bracket->getGroupStandings($tournament);
            // Serialize standings
            foreach ($raw['standings'] as $group => $rows) {
                foreach ($rows as $uid => $stats) {
                    $player = $raw['players'][$uid] ?? null;
                    $groupData[$group][] = [
                        'uid'      => $uid,
                        'username' => $player?->username ?? '?',
                        'avatar'   => $player?->avatar,
                        'pts'      => $stats['pts'],
                        'w'        => $stats['w'],
                        'l'        => $stats['l'],
                        'gf'       => $stats['gf'],
                        'ga'       => $stats['ga'],
                        'played'   => $stats['played'],
                    ];
                }
            }
            // Group matches — include BO/Ban/Agg/Wins info
            $boGroup  = $tournament->getBoForPhase('group');
            $banGroup = $tournament->getBanCountForPhase('group');
            foreach ($raw['matches'] as $m) {
                $legs      = $m->relationLoaded('seriesLegs') ? $m->seriesLegs : collect([$m]);
                $donelegs  = $legs->where('status', 'completed');
                $agg1      = $donelegs->sum('score1');
                $agg2      = $donelegs->sum('score2');
                $wins1     = $donelegs->filter(fn($l) => $l->winner_id === $m->player1_id)->count();
                $wins2     = $donelegs->filter(fn($l) => $l->winner_id === $m->player2_id)->count();
                $groupData['matches'][] = [
                    'id'       => $m->id,
                    'group'    => $m->group_name,
                    'p1'       => $m->player1?->username,
                    'p2'       => $m->player2?->username,
                    'score1'   => $m->score1,
                    'score2'   => $m->score2,
                    'winner_id'=> $m->winner_id,
                    'is_draw'  => $m->is_draw,
                    'status'   => $m->status,
                    'agg1'     => $agg1,
                    'agg2'     => $agg2,
                    'w1'       => $wins1,
                    'w2'       => $wins2,
                ];
            }
            $groupData['bo_group']  = $boGroup;
            $groupData['ban_group'] = $banGroup;
        }

        $rounds = $this->bracket->getKnockoutBracket($tournament);
        foreach ($rounds as $round => $matches) {
            foreach ($matches as $m) {
                $knockoutData[$round][] = [
                    'id'        => $m->id,
                    'p1'        => ['id' => $m->player1_id, 'name' => $m->player1?->username, 'avatar' => $m->player1?->avatar],
                    'p2'        => ['id' => $m->player2_id, 'name' => $m->player2?->username, 'avatar' => $m->player2?->avatar],
                    'score1'    => $m->score1,
                    'score2'    => $m->score2,
                    'winner_id' => $m->winner_id,
                    'status'    => $m->status,
                ];
            }
        }

        return response()->json([
            'format'        => $tournament->format,
            'current_phase' => $tournament->current_phase,
            'status'        => $tournament->status,
            'group'         => $groupData,
            'knockout'      => $knockoutData,
        ]);
    }
}
