<?php
require_once '../core/bootstrap.php';

// --- Authentication and Role Check ---
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'commissioner') {
    header('Location: login.php');
    exit();
}
$commissioner_id = $_SESSION['user_id'];

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: commissioner_matches.php');
    exit();
}

$action = $_POST['action'] ?? null;
$fixture_id = filter_input(INPUT_POST, 'fixture_id', FILTER_VALIDATE_INT);
$data = $_POST; // Use the whole POST array for data
$notificationModel = new Notification();
$lineupModel = new Lineup();
$fixtureModel = new Fixture();

if (!$action || !$fixture_id) {
    $_SESSION['flash_message'] = ['type' => 'error', 'text' => 'Invalid action or fixture ID.'];
    header('Location: commissioner_matches.php');
    exit();
}

$fixtureModel = new Fixture();
$eventModel = new MatchEvent();
$fineModel = new Fine();
$suspensionModel = new PlayerSuspension();
$settingModel = new Setting();
$teamModel = new Team();
$clubModel = new Club();

// Instantiate the service with all its dependencies
$liveScorerService = new LiveScorerService($fixtureModel, $eventModel, $fineModel, $suspensionModel, $settingModel);

// --- Security Check: Ensure commissioner is assigned to this fixture ---
$fixture = $fixtureModel->findById($fixture_id);
if (!$fixture || $fixture->commissioner_id != $commissioner_id) {
    $_SESSION['flash_message'] = ['type' => 'error', 'text' => 'You are not assigned to this fixture.'];
    header('Location: commissioner_matches.php');
    exit();
}

$success = false;
$message = 'An unknown error occurred.';

try {
    switch ($action) {
        case 'start_match':
            $success = $liveScorerService->startMatch($fixture_id);
            $message = $success ? 'Match started successfully.' : 'Failed to start match.';
            if ($success) {
                // Notify players in the starting lineup
                $fixture = $fixtureModel->findById($fixture_id);
                $home_lineup = $lineupModel->getLineupForFixture($fixture_id, $fixture->home_team_id);
                $away_lineup = $lineupModel->getLineupForFixture($fixture_id, $fixture->away_team_id);
                
                $all_starters = array_merge(array_keys($home_lineup->starters ?? []), array_keys($away_lineup->starters ?? []));
                
                foreach ($all_starters as $player_id) {
                    $notificationModel->create($player_id, 'match_start', "The match between {$fixture->home_team_name} and {$fixture->away_team_name} has started! You are in the starting lineup.");
                }

                // Notify subs
                $all_subs = array_merge($home_lineup->substitutes ?? [], $away_lineup->substitutes ?? []);
                foreach ($all_subs as $player_id) {
                    $notificationModel->create($player_id, 'match_start', "The match between {$fixture->home_team_name} and {$fixture->away_team_name} has started. You are on the bench.");
                }
            }
            break;

        case 'end_first_half':
            $success = $liveScorerService->endFirstHalf($fixture_id);
            $message = $success ? 'First half ended.' : 'Failed to end first half.';
            break;

        case 'start_second_half':
            $success = $liveScorerService->startSecondHalf($fixture_id);
            $message = $success ? 'Second half started.' : 'Failed to start second half.';
            break;

        case 'endSecondHalf':
            $success = $liveScorerService->endSecondHalf($fixture_id);
            $message = $success ? 'Second half ended.' : 'Failed to end second half.';
            break;

        case 'end_match':
            // Ensure an empty string from the form becomes null to satisfy the type hint.
            $motm_player_id = !empty($data['motm_player_id']) ? (int)$data['motm_player_id'] : null;
            $success = $liveScorerService->endMatch($fixture_id, $motm_player_id);
            $message = $success ? 'Match has been finished.' : 'Failed to end match.';

            if ($success) {
                // --- Notify Club Members of Full Time Result ---
                $fixture = $fixtureModel->findById($fixture_id); // Refresh to get final scores
                
                // --- Calculate Fantasy Points ---
                if (class_exists('FantasyPoints')) {
                    $fantasyPointsModel = new FantasyPoints();
                    $fantasyPointsModel->recalculateForFixture($fixture_id);
                }

                $home_team = $teamModel->findById($fixture->home_team_id);
                $away_team = $teamModel->findById($fixture->away_team_id);
            
                $result_msg = "Full Time: {$fixture->home_team_name} {$fixture->home_team_score} - {$fixture->away_team_score} {$fixture->away_team_name}.";
            
                $db = new Database();
                if ($home_team && $home_team->club_id) {
                    $db->query("SELECT user_id FROM memberships WHERE club_id = :club_id AND expiry_date >= CURDATE()");
                    $db->bind(':club_id', $home_team->club_id);
                    $members = $db->resultSet();
                    foreach ($members as $member) {
                        $notificationModel->create($member->user_id, 'match_result', $result_msg);
                    }
                }
                if ($away_team && $away_team->club_id) {
                    $db->query("SELECT user_id FROM memberships WHERE club_id = :club_id AND expiry_date >= CURDATE()");
                    $db->bind(':club_id', $away_team->club_id);
                    $members = $db->resultSet();
                    foreach ($members as $member) {
                        $notificationModel->create($member->user_id, 'match_result', $result_msg);
                    }
                }
            }
            break;

        case 'log_event':
            $result = $liveScorerService->logEvent($data, $fixture);
            $success = $result['success'];
            $message = $success ? 'Event logged successfully.' : ($result['message'] ?? 'Failed to log event.');
            
            if ($success && in_array($data['event_type'], ['yellow_card', 'red_card']) && !empty($data['player_id'])) {
                $playerModel = new Player();
                $player = $playerModel->getPlayerDetailsById($data['player_id']);
                $player_full_name = $player ? ($player->first_name . ' ' . $player->last_name) : 'A player';

                $card_name = ucwords(str_replace('_', ' ', $data['event_type']));
                // $fixture is already loaded from the security check at the top of the file
                $opponent_name = ($data['team_id'] == $fixture->home_team_id ? $fixture->away_team_name : $fixture->home_team_name);
                $msg_player = "You received a {$card_name} in the match against {$opponent_name}. This may result in a fine or suspension.";
                $notificationModel->create($data['player_id'], 'discipline', $msg_player);

                if ($data['event_type'] === 'red_card' && $team = $teamModel->findById($data['team_id'])) {
                    $msg_manager = "{$player_full_name} received a red card against {$opponent_name} and will be suspended.";
                    if ($team->manager_id) $notificationModel->create($team->manager_id, 'suspension', $msg_manager);
                }

                // --- Automatic Fine Issuance ---
                $settings = $settingModel->getAll();
                $fine_amount = 0;
                $reason = '';

                if ($data['event_type'] === 'yellow_card') {
                    $fine_amount = (float)($settings['fine_yellow_card'] ?? 0);
                    $reason = 'Yellow Card';
                } elseif ($data['event_type'] === 'red_card') {
                    $fine_amount = (float)($settings['fine_red_card'] ?? 0);
                    $reason = 'Red Card';
                }

                if ($fine_amount > 0 && $player) {
                    $fineData = [
                        'entity_type' => 'player',
                        'entity_id' => $data['player_id'],
                        'reason' => $reason . ' in match vs ' . $opponent_name,
                        'amount' => $fine_amount
                    ];
                    $fineModel->create($fineData);
                }
            }
            break;

        case 'undo_last_event':
            $result = $liveScorerService->undoLastEvent($fixture_id, $fixture);
            $success = $result['success'];
            $message = $success ? 'Last event undone.' : $result['message'];
            break;

        default:
            $message = 'Invalid action specified.';
            break;
    }
} catch (Exception $e) {
    $success = false;
    $message = 'An internal server error occurred: ' . $e->getMessage();
}

// Set flash message and redirect back
$_SESSION['flash_message'] = [
    'type' => $success ? 'success' : 'error',
    'text' => $message
];

header('Location: live_scorer.php?fixture_id=' . $fixture_id);
exit();
?>
```

### 2. Update `app/live_scorer.php`

I will now replace the existing JavaScript in your `live_scorer.php` file with the fully functional implementation.

```diff