<?php

declare(strict_types=1);

require_once __DIR__ . '/helpers.php';

$fixtureModuleBoot = 'fixture_module_boot';
$validateFixturePayload = 'validate_fixture_payload';
$findFixtureOrAbort = 'find_fixture_or_abort';
$fixtureHasDependencies = 'fixture_has_dependencies';
$validateFixtureGenerationPayload = 'validate_fixture_generation_payload';
$generateFixtureSchedule = 'generate_fixture_schedule';
$fixtureApplyAutoOfficialAssignments = 'fixture_apply_auto_official_assignments';
$validateFixturePostponementPayload = 'validate_fixture_postponement_payload';
$validateFixtureReschedulePayload = 'validate_fixture_reschedule_payload';
$fixturePostpone = 'fixture_postpone';
$fixtureReschedule = 'fixture_reschedule';

$fixtureModuleBoot();

if (!is_post()) {
    redirect('app/modules/fixtures/index.php');
}

require_valid_csrf();

$action = (string) ($_POST['action'] ?? '');

if ($action === 'create') {
    remember_old_input($_POST);
    $errors = [];
    $payload = $validateFixturePayload($_POST, $errors);

    if ($errors !== []) {
        flash('errors', $errors);
        flash('error', ['type' => 'danger', 'message' => 'Please correct the fixture form errors.']);
        redirect('app/modules/fixtures/create.php' . ($payload['competition_id'] > 0 ? '?competition_id=' . $payload['competition_id'] : ''));
    }

    $payload = $fixtureApplyAutoOfficialAssignments($payload);

    db_query(
        'INSERT INTO fixtures (
            competition_id, season_id, matchday, home_club_id, away_club_id, venue_id,
            match_date, match_time, status, referee_id, assistant_referee_1,
            assistant_referee_2, fourth_official, match_commissioner, created_at, updated_at
         ) VALUES (
            :competition_id, :season_id, :matchday, :home_club_id, :away_club_id, :venue_id,
            :match_date, :match_time, :status, :referee_id, :assistant_referee_1,
            :assistant_referee_2, :fourth_official, :match_commissioner, NOW(), NOW()
         )',
        $payload
    );

    $fixtureId = (int) db()->lastInsertId();
    audit_log('create_fixture', 'fixtures', $fixtureId, null, $payload);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Fixture created successfully.']);
    redirect('app/modules/fixtures/view.php?id=' . $fixtureId);
}

if ($action === 'update') {
    $fixtureId = (int) ($_POST['id'] ?? 0);
    $existingFixture = $findFixtureOrAbort($fixtureId);
    remember_old_input($_POST);
    $errors = [];
    $payload = $validateFixturePayload($_POST, $errors, $fixtureId);

    if ($errors !== []) {
        flash('errors', $errors);
        flash('error', ['type' => 'danger', 'message' => 'Please correct the fixture form errors.']);
        redirect('app/modules/fixtures/edit.php?id=' . $fixtureId);
    }

    db_query(
        'UPDATE fixtures
         SET competition_id = :competition_id,
             season_id = :season_id,
             matchday = :matchday,
             home_club_id = :home_club_id,
             away_club_id = :away_club_id,
             venue_id = :venue_id,
             match_date = :match_date,
             match_time = :match_time,
             status = :status,
             referee_id = :referee_id,
             assistant_referee_1 = :assistant_referee_1,
             assistant_referee_2 = :assistant_referee_2,
             fourth_official = :fourth_official,
             match_commissioner = :match_commissioner,
             updated_at = NOW()
         WHERE id = :id',
        $payload + ['id' => $fixtureId]
    );

    audit_log('update_fixture', 'fixtures', $fixtureId, $existingFixture, $payload);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Fixture updated successfully.']);
    redirect('app/modules/fixtures/view.php?id=' . $fixtureId);
}

if ($action === 'generate') {
    if (!can_generate_fixtures()) {
        abort_request(403, 'Access denied', 'You do not have permission to generate fixtures.');
    }

    remember_old_input($_POST);
    $errors = [];
    $payload = $validateFixtureGenerationPayload($_POST, $errors);

    if ($errors !== []) {
        flash('errors', $errors);
        flash('error', ['type' => 'danger', 'message' => 'Please correct the fixture generation form errors.']);
        redirect('app/modules/fixtures/generate.php' . ($payload['competition_id'] > 0 ? '?competition_id=' . $payload['competition_id'] : ''));
    }

    $createdCount = $generateFixtureSchedule($payload);
    clear_old_input();
    audit_log('generate_fixtures', 'competitions', (int) $payload['competition_id'], null, $payload + ['created_count' => $createdCount]);
    flash('success', ['type' => 'success', 'message' => sprintf('%d fixtures generated successfully.', $createdCount)]);
    redirect('app/modules/fixtures/index.php?competition_id=' . (int) $payload['competition_id']);
}

if ($action === 'delete') {
    $fixtureId = (int) ($_POST['id'] ?? 0);
    $existingFixture = $findFixtureOrAbort($fixtureId);

    if ($fixtureHasDependencies($fixtureId)) {
        flash('error', ['type' => 'danger', 'message' => 'This fixture cannot be deleted while match results or match events still exist.']);
        redirect('app/modules/fixtures/delete.php?id=' . $fixtureId);
    }

    db_query('DELETE FROM fixtures WHERE id = :id', ['id' => $fixtureId]);
    audit_log('delete_fixture', 'fixtures', $fixtureId, $existingFixture, null);
    flash('success', ['type' => 'success', 'message' => 'Fixture deleted successfully.']);
    redirect('app/modules/fixtures/index.php');
}

if ($action === 'postpone') {
    $fixtureId = (int) ($_POST['id'] ?? 0);
    $fixture = $findFixtureOrAbort($fixtureId);
    $errors = [];
    $payload = $validateFixturePostponementPayload($_POST, $errors);

    if ($errors !== []) {
        remember_old_input($_POST);
        flash('errors', $errors);
        flash('error', ['type' => 'danger', 'message' => 'Provide a postponement reason before saving.']);
        redirect('app/modules/fixtures/view.php?id=' . $fixtureId);
    }

    $fixturePostpone($fixture, $payload['postponement_reason']);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Fixture postponed and news published successfully.']);
    redirect('app/modules/fixtures/view.php?id=' . $fixtureId);
}

if ($action === 'reschedule') {
    $fixtureId = (int) ($_POST['id'] ?? 0);
    $fixture = $findFixtureOrAbort($fixtureId);
    $errors = [];
    $payload = $validateFixtureReschedulePayload($_POST, $errors, $fixture);

    if ($errors !== []) {
        remember_old_input($_POST);
        flash('errors', $errors);
        flash('error', ['type' => 'danger', 'message' => 'Provide a valid new date, time, and note before rescheduling.']);
        redirect('app/modules/fixtures/view.php?id=' . $fixtureId);
    }

    $fixtureReschedule($fixture, $payload);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Fixture rescheduled and news published successfully.']);
    redirect('app/modules/fixtures/view.php?id=' . $fixtureId);
}

redirect('app/modules/fixtures/index.php');
