<?php

class LiveScorerService
{
    private $fixtureModel;
    private $eventModel;
    private $fineModel;
    private $suspensionModel;
    private $settingModel;

    public function __construct(Fixture $fixtureModel, MatchEvent $eventModel, Fine $fineModel, PlayerSuspension $suspensionModel, Setting $settingModel)
    {
        $this->fixtureModel = $fixtureModel;
        $this->eventModel = $eventModel;
        $this->fineModel = $fineModel;
        $this->suspensionModel = $suspensionModel;
        $this->settingModel = $settingModel;
    }

    public function startMatch(int $fixture_id): bool
    {
        return $this->fixtureModel->updateStatus($fixture_id, 'live', 'first_half_start_time');
    }

    public function endFirstHalf(int $fixture_id): bool
    {
        return $this->fixtureModel->updateStatus($fixture_id, 'half_time', 'first_half_end_time');
    }

    public function startSecondHalf(int $fixture_id): bool
    {
        return $this->fixtureModel->updateStatus($fixture_id, 'live', 'second_half_start_time');
    }

    public function endSecondHalf(int $fixture_id): bool
    {
        return $this->fixtureModel->updateStatus($fixture_id, 'full_time', 'second_half_end_time');
    }

    public function endMatch(int $fixture_id, ?int $motm_player_id): bool
    {
        // Here you could also log the MOTM if the column exists on the fixtures table
        return $this->fixtureModel->updateStatus($fixture_id, 'finished');
    }

    public function logEvent(array $data, object $fixture): array
    {
        $event_type = $data['event_type'] ?? null;
        $player_id = !empty($data['player_id']) ? (int)$data['player_id'] : null;

        // Log the primary event
        $event_id = $this->eventModel->log($data);
        if (!$event_id) {
            return ['success' => false, 'message' => 'Failed to log the primary event.'];
        }

        // --- Handle automatic disciplinary actions ---
        $settings = $this->settingModel->getAll();
        $fine_yellow_card = (float)($settings['fine_yellow_card'] ?? 0);
        $fine_red_card = (float)($settings['fine_red_card'] ?? 0);
        $suspension_red_card = (int)($settings['suspension_red_card'] ?? 0);

        if ($event_type === 'yellow_card' && $player_id && $fine_yellow_card > 0) {
            $this->fineModel->create([
                'entity_type' => 'player',
                'entity_id' => $player_id,
                'reason' => 'Yellow Card (Fixture #' . $fixture->id . ')',
                'amount' => $fine_yellow_card
            ]);
        }

        if ($event_type === 'red_card' && $player_id) {
            // Issue fine for red card
            if ($fine_red_card > 0) {
                $this->fineModel->create([
                    'entity_type' => 'player',
                    'entity_id' => $player_id,
                    'reason' => 'Red Card (Fixture #' . $fixture->id . ')',
                    'amount' => $fine_red_card
                ]);
            }
            // Issue suspension for red card
            if ($suspension_red_card > 0) {
                $this->suspensionModel->create([
                    'player_id' => $player_id,
                    'fixture_incurred_id' => $fixture->id,
                    'reason' => 'Red Card',
                    'matches_to_serve' => $suspension_red_card
                ]);
            }
        }

        // --- Handle score changes ---
        if ($event_type === 'goal' || $event_type === 'penalty_scored') {
            $this->fixtureModel->incrementScore($fixture->id, $data['team_id']);
        } elseif ($event_type === 'own_goal') {
            // An own goal increments the score of the OPPOSING team
            $opposing_team_id = ($data['team_id'] == $fixture->home_team_id) ? $fixture->away_team_id : $fixture->home_team_id;
            $this->fixtureModel->incrementScore($fixture->id, $opposing_team_id);
        }

        return ['success' => true];
    }

    public function undoLastEvent(int $fixture_id, object $fixture): array
    {
        $last_event = $this->eventModel->getLatestEventForFixture($fixture_id);
        if (!$last_event) {
            return ['success' => false, 'message' => 'No event to undo.'];
        }

        // --- Reverse any automatic disciplinary actions ---
        if ($last_event->event_type === 'yellow_card' && $last_event->player_id) {
            $this->fineModel->deleteByEventDetails(
                $last_event->player_id,
                $fixture->id,
                'Yellow Card (Fixture #' . $fixture->id . ')'
            );
        } elseif ($last_event->event_type === 'red_card' && $last_event->player_id) {
            $this->fineModel->deleteByEventDetails(
                $last_event->player_id,
                $fixture->id,
                'Red Card (Fixture #' . $fixture->id . ')'
            );
            $this->suspensionModel->deleteByFixtureAndPlayer($fixture->id, $last_event->player_id);
        }

        // --- Reverse score changes ---
        if ($last_event->event_type === 'goal' || $last_event->event_type === 'penalty_scored') {
            // This is a simplified decrement. A more robust solution would check the score isn't already 0.
            $columnToUpdate = ($last_event->team_id == $fixture->home_team_id) ? 'home_team_score' : 'away_team_score';
            $this->db->query("UPDATE fixtures SET {$columnToUpdate} = GREATEST(0, {$columnToUpdate} - 1) WHERE id = :id");
            $this->db->bind(':id', $fixture_id);
            $this->db->execute();
        } elseif ($last_event->event_type === 'own_goal') {
            // An own goal increments the score of the OPPOSING team, so we decrement it here.
            $opposing_team_id = ($last_event->team_id == $fixture->home_team_id) ? $fixture->away_team_id : $fixture->home_team_id;
            $columnToUpdate = ($opposing_team_id == $fixture->home_team_id) ? 'home_team_score' : 'away_team_score';
            $this->db->query("UPDATE fixtures SET {$columnToUpdate} = GREATEST(0, {$columnToUpdate} - 1) WHERE id = :id");
            $this->db->bind(':id', $fixture_id);
            $this->db->execute();
        }

        // --- Delete the event itself ---
        $deleted = $this->eventModel->deleteById($last_event->id);
        return ['success' => $deleted, 'message' => $deleted ? 'Event undone.' : 'Failed to delete event.'];
    }
}