<?php

declare(strict_types=1);

require_once __DIR__ . '/helpers.php';

$protestModuleBoot = 'protest_module_boot';
$validateProtestPayload = 'validate_protest_payload';
$findProtestOrAbort = 'find_protest_or_abort';
$validateProtestDecisionPayload = 'validate_protest_decision_payload';
$canDecideProtests = 'can_decide_protests';

$protestModuleBoot();

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

require_valid_csrf();

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

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

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

    $evidenceFile = null;
    if (isset($_FILES['evidence_file']) && ($_FILES['evidence_file']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
        try {
            $evidenceFile = upload_file($_FILES['evidence_file'], [
                'directory' => 'protests',
                'max_size' => 5 * 1024 * 1024,
                'allowed_mime_types' => ['application/pdf', 'image/jpeg', 'image/png', 'image/webp'],
                'allowed_extensions' => ['pdf', 'jpg', 'jpeg', 'png', 'webp'],
            ]);
        } catch (RuntimeException $exception) {
            flash('errors', ['evidence_file' => $exception->getMessage()]);
            flash('error', ['type' => 'danger', 'message' => $exception->getMessage()]);
            redirect('app/modules/protests/create.php' . ($payload['fixture_id'] > 0 ? '?fixture_id=' . $payload['fixture_id'] : ''));
        }
    }

    db_query(
        'INSERT INTO protests (
            fixture_id, protesting_club_id, against_club_id, title, complaint,
            evidence_file, status, decision, created_at, resolved_at
         ) VALUES (
            :fixture_id, :protesting_club_id, :against_club_id, :title, :complaint,
            :evidence_file, :status, :decision, NOW(), NULL
         )',
        $payload + ['evidence_file' => $evidenceFile]
    );

    $protestId = (int) db()->lastInsertId();
    audit_log('create_protest', 'protests', $protestId, null, $payload + ['evidence_file' => $evidenceFile]);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Protest created successfully.']);
    redirect('app/modules/protests/view.php?id=' . $protestId);
}

if ($action === 'update') {
    $protestId = (int) ($_POST['id'] ?? 0);
    $existingProtest = $findProtestOrAbort($protestId);
    remember_old_input($_POST);
    $errors = [];
    $payload = $validateProtestPayload($_POST, $errors, $protestId);

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

    $evidenceFile = $existingProtest['evidence_file'];
    if (isset($_FILES['evidence_file']) && ($_FILES['evidence_file']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
        try {
            $evidenceFile = upload_file($_FILES['evidence_file'], [
                'directory' => 'protests',
                'max_size' => 5 * 1024 * 1024,
                'allowed_mime_types' => ['application/pdf', 'image/jpeg', 'image/png', 'image/webp'],
                'allowed_extensions' => ['pdf', 'jpg', 'jpeg', 'png', 'webp'],
            ]);
            delete_uploaded_file($existingProtest['evidence_file']);
        } catch (RuntimeException $exception) {
            flash('errors', ['evidence_file' => $exception->getMessage()]);
            flash('error', ['type' => 'danger', 'message' => $exception->getMessage()]);
            redirect('app/modules/protests/edit.php?id=' . $protestId);
        }
    }

    db_query(
        'UPDATE protests
         SET fixture_id = :fixture_id,
             protesting_club_id = :protesting_club_id,
             against_club_id = :against_club_id,
             title = :title,
             complaint = :complaint,
             evidence_file = :evidence_file,
             status = :status,
             decision = :decision
         WHERE id = :id',
        $payload + ['evidence_file' => $evidenceFile, 'id' => $protestId]
    );

    audit_log('update_protest', 'protests', $protestId, $existingProtest, $payload + ['evidence_file' => $evidenceFile]);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Protest updated successfully.']);
    redirect('app/modules/protests/view.php?id=' . $protestId);
}

if ($action === 'decide') {
    if (!$canDecideProtests()) {
        abort_request(403, 'Access denied', 'You do not have permission to decide protests.');
    }

    $protestId = (int) ($_POST['id'] ?? 0);
    $existingProtest = $findProtestOrAbort($protestId);
    $errors = [];
    $payload = $validateProtestDecisionPayload($_POST, $errors);

    if ($errors !== []) {
        flash('error', ['type' => 'danger', 'message' => reset($errors) ?: 'Please correct the protest decision form errors.']);
        redirect('app/modules/protests/view.php?id=' . $protestId);
    }

    db_query(
        'UPDATE protests
         SET status = :status,
             decision = :decision,
             resolved_at = :resolved_at
         WHERE id = :id',
        $payload + ['id' => $protestId]
    );

    audit_log('decide_protest', 'protests', $protestId, $existingProtest, $payload);
    flash('success', ['type' => 'success', 'message' => 'Protest decision saved successfully.']);
    redirect('app/modules/protests/view.php?id=' . $protestId);
}

if ($action === 'delete') {
    $protestId = (int) ($_POST['id'] ?? 0);
    $existingProtest = $findProtestOrAbort($protestId);
    db_query('DELETE FROM protests WHERE id = :id', ['id' => $protestId]);
    delete_uploaded_file($existingProtest['evidence_file']);
    audit_log('delete_protest', 'protests', $protestId, $existingProtest, null);
    flash('success', ['type' => 'success', 'message' => 'Protest deleted successfully.']);
    redirect('app/modules/protests/index.php');
}

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