<?php
declare(strict_types=1);

namespace App\Modules\Tournaments\Controllers;

use App\Core\Controller;
use App\Core\App;
use App\Core\Request;
use App\Core\Response;
use App\Modules\Tournaments\Models\Tournament;
use App\Modules\Tournaments\Models\TournamentParticipant;
use App\Modules\Tournaments\Models\TournamentMatch;
use App\Modules\Tournaments\Services\TournamentService;

class TournamentController extends Controller
{
    /**
     * List tournaments.
     */
    public function index(Request $request): Response
    {
        $this->authorize('tournament.view');

        $filters = [
            'q'               => $request->get('q', ''),
            'discipline_id'   => $request->get('discipline_id', ''),
            'status'          => $request->get('status', ''),
            'tournament_type' => $request->get('tournament_type', ''),
            'format'          => $request->get('format', ''),
        ];

        $page = max(1, (int) $request->get('page', '1'));
        $result = Tournament::search($filters, 25, $page);

        $db = App::getInstance()->db();
        $disciplines = $db->select("SELECT id, name_ar FROM sport_disciplines WHERE is_active = 1 ORDER BY name_ar ASC", []);

        return $this->view('Tournaments.Views.index', [
            'tournaments' => $result['data'],
            'pagination'  => $result['pagination'],
            'filters'     => $filters,
            'disciplines' => $disciplines,
        ]);
    }

    /**
     * Show create form.
     */
    public function create(Request $request): Response
    {
        $this->authorize('tournament.manage');

        $db = App::getInstance()->db();
        $disciplines = $db->select("SELECT id, name_ar FROM sport_disciplines WHERE is_active = 1 ORDER BY name_ar ASC", []);
        $facilities = $db->select("SELECT id, name_ar FROM facilities WHERE is_active = 1 ORDER BY name_ar ASC", []);

        return $this->view('Tournaments.Views.create', [
            'disciplines' => $disciplines,
            'facilities'  => $facilities,
        ]);
    }

    /**
     * Store new tournament.
     */
    public function store(Request $request): Response
    {
        $this->authorize('tournament.manage');

        $data = $this->validated($_POST, [
            'name_ar'             => 'required',
            'discipline_id'       => 'required|numeric',
            'tournament_type'     => 'required',
            'format'              => 'required',
            'start_date'          => 'required',
            'end_date'            => 'nullable',
            'age_group'           => 'nullable',
            'gender'              => 'nullable',
            'max_participants'    => 'nullable|numeric',
            'min_participants'    => 'nullable|numeric',
            'registration_start'  => 'nullable',
            'registration_end'    => 'nullable',
            'facility_id'         => 'nullable|numeric',
            'entry_fee'           => 'nullable|numeric',
            'prize_description_ar'=> 'nullable',
            'rules_ar'            => 'nullable',
            'notes'               => 'nullable',
        ]);

        $data['status'] = 'draft';

        $employee = $this->currentEmployee();
        if ($employee) {
            $data['organizer_id'] = (int) $employee->id;
        }

        try {
            $tournament = TournamentService::createTournament($data);
            return $this->redirect('/tournaments/' . $tournament['id'])->withSuccess('تم إنشاء البطولة بنجاح');
        } catch (\Throwable $e) {
            return $this->back()->withError('خطأ: ' . $e->getMessage());
        }
    }

    /**
     * Show tournament details with bracket/standings.
     */
    public function show(Request $request, int $id): Response
    {
        $this->authorize('tournament.view');

        $db = App::getInstance()->db();

        $tournament = $db->selectOne(
            "SELECT t.*, d.name_ar AS discipline_name, f.name_ar AS facility_name
             FROM tournaments t
             LEFT JOIN sport_disciplines d ON d.id = t.discipline_id
             LEFT JOIN facilities f ON f.id = t.facility_id
             WHERE t.id = ?",
            [$id]
        );

        if (!$tournament) {
            throw new \RuntimeException('البطولة غير موجودة', 404);
        }

        $participants = TournamentParticipant::getForTournament($id);
        $matches = TournamentMatch::getForTournament($id);
        $bracket = TournamentMatch::getBracket($id);
        $standings = TournamentParticipant::getStandings($id);

        return $this->view('Tournaments.Views.show', [
            'tournament'   => $tournament,
            'participants' => $participants,
            'matches'      => $matches,
            'bracket'      => $bracket,
            'standings'    => $standings,
        ]);
    }

    /**
     * Show edit form.
     */
    public function edit(Request $request, int $id): Response
    {
        $this->authorize('tournament.manage');

        $tournament = Tournament::findOrFail($id);

        $db = App::getInstance()->db();
        $disciplines = $db->select("SELECT id, name_ar FROM sport_disciplines WHERE is_active = 1 ORDER BY name_ar ASC", []);
        $facilities = $db->select("SELECT id, name_ar FROM facilities WHERE is_active = 1 ORDER BY name_ar ASC", []);

        return $this->view('Tournaments.Views.create', [
            'tournament'  => $tournament->toArray(),
            'disciplines' => $disciplines,
            'facilities'  => $facilities,
            'isEdit'      => true,
        ]);
    }

    /**
     * Update tournament.
     */
    public function update(Request $request, int $id): Response
    {
        $this->authorize('tournament.manage');

        $tournament = Tournament::findOrFail($id);

        $data = $this->validated($_POST, [
            'name_ar'             => 'required',
            'discipline_id'       => 'required|numeric',
            'tournament_type'     => 'required',
            'format'              => 'required',
            'start_date'          => 'required',
            'end_date'            => 'nullable',
            'age_group'           => 'nullable',
            'gender'              => 'nullable',
            'max_participants'    => 'nullable|numeric',
            'min_participants'    => 'nullable|numeric',
            'registration_start'  => 'nullable',
            'registration_end'    => 'nullable',
            'facility_id'         => 'nullable|numeric',
            'entry_fee'           => 'nullable|numeric',
            'prize_description_ar'=> 'nullable',
            'rules_ar'            => 'nullable',
            'notes'               => 'nullable',
        ]);

        try {
            $tournament->update($data);
            return $this->redirect('/tournaments/' . $id)->withSuccess('تم تحديث البطولة بنجاح');
        } catch (\Throwable $e) {
            return $this->back()->withError('خطأ: ' . $e->getMessage());
        }
    }

    /**
     * Open registration.
     */
    public function openRegistration(Request $request, int $id): Response
    {
        $this->authorize('tournament.manage');

        $tournament = Tournament::findOrFail($id);
        $tournament->update(['status' => 'registration_open']);

        return $this->redirect('/tournaments/' . $id)->withSuccess('تم فتح التسجيل في البطولة');
    }

    /**
     * Close registration.
     */
    public function closeRegistration(Request $request, int $id): Response
    {
        $this->authorize('tournament.manage');

        $tournament = Tournament::findOrFail($id);
        $tournament->update(['status' => 'registration_closed']);

        return $this->redirect('/tournaments/' . $id)->withSuccess('تم إغلاق التسجيل في البطولة');
    }

    /**
     * Generate bracket.
     */
    public function generateBracket(Request $request, int $id): Response
    {
        $this->authorize('tournament.manage');

        try {
            TournamentService::generateBracket($id);
            return $this->redirect('/tournaments/' . $id)->withSuccess('تم توليد شجرة المباريات بنجاح');
        } catch (\Throwable $e) {
            return $this->back()->withError('خطأ: ' . $e->getMessage());
        }
    }

    /**
     * Complete tournament.
     */
    public function complete(Request $request, int $id): Response
    {
        $this->authorize('tournament.manage');

        try {
            TournamentService::completeTournament($id);
            return $this->redirect('/tournaments/' . $id)->withSuccess('تم إنهاء البطولة وتحديد الفائز');
        } catch (\Throwable $e) {
            return $this->back()->withError('خطأ: ' . $e->getMessage());
        }
    }
}
