<?php

declare(strict_types=1);

require_once __DIR__ . '/helpers.php';

$playerModuleBoot = 'player_module_boot';
$validatePlayerPayload = 'validate_player_payload';
$playerGenerateRegistrationNumber = 'player_generate_registration_number';
$createPlayerRecord = 'create_player_record';
$playerParseBulkCsvUpload = 'player_parse_bulk_csv_upload';
$findPlayerOrAbort = 'find_player_or_abort';
$findPlayerDocumentOrAbort = 'find_player_document_or_abort';
$validatePlayerDocumentPayload = 'validate_player_document_payload';
$canManagePlayerApproval = 'can_manage_player_approval';
$playerEligibilityOptions = 'player_eligibility_options';
$playerFullName = 'player_full_name';
$playerHasDependencies = 'player_has_dependencies';
$playerDocuments = 'player_documents';

$playerModuleBoot();

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

require_valid_csrf();

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

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

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

    $photoPath = null;
    if (isset($_FILES['photo']) && ($_FILES['photo']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
        try {
            $photoPath = upload_file($_FILES['photo'], ['directory' => 'players', 'max_size' => 2 * 1024 * 1024]);
        } catch (RuntimeException $exception) {
            flash('errors', ['photo' => $exception->getMessage()]);
            flash('error', ['type' => 'danger', 'message' => $exception->getMessage()]);
            redirect('app/modules/players/create.php' . (!is_club_admin() && $payload['club_id'] > 0 ? '?club_id=' . $payload['club_id'] : ''));
        }
    }

    $payload['registration_number'] = $playerGenerateRegistrationNumber((int) $payload['club_id']);

    $playerId = $createPlayerRecord($payload, $photoPath);
    audit_log('create_player', 'players', $playerId, null, $payload + ['photo' => $photoPath]);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Player created successfully.']);
    redirect('app/modules/players/view.php?id=' . $playerId);
}

if ($action === 'bulk_import') {
    remember_old_input($_POST);
    $errors = [];
    $clubId = is_club_admin() ? (int) user_club_id() : (int) ($_POST['club_id'] ?? 0);

    if ($clubId <= 0) {
        $errors['club_id'] = 'Select the club that owns the uploaded squad.';
    } elseif (get_club_by_id($clubId) === null) {
        $errors['club_id'] = 'Selected club is invalid.';
    } else {
        require_club_scope($clubId);
    }

    $rows = $playerParseBulkCsvUpload($_FILES['bulk_file'] ?? [], $errors);

    if ($errors !== []) {
        flash('errors', $errors);
        flash('error', ['type' => 'danger', 'message' => 'Bulk player upload could not be started.']);
        redirect('app/modules/players/bulk.php' . (!is_club_admin() && $clubId > 0 ? '?club_id=' . $clubId : ''));
    }

    $rowErrors = [];
    $validatedRows = [];
    $seenNins = [];
    $seenJerseyNumbers = [];

    foreach ($rows as $row) {
        $rowInput = $row['data'] + ['club_id' => $clubId];
        $validationErrors = [];
        $payload = $validatePlayerPayload($rowInput, $validationErrors);

        $nin = trim((string) ($payload['nin'] ?? ''));
        if ($nin !== '' && isset($seenNins[$nin])) {
            $validationErrors['nin'] = 'NIN is duplicated inside this CSV upload.';
        }

        if (($payload['jersey_number'] ?? null) !== null) {
            $jerseyKey = (string) $payload['jersey_number'];
            if (isset($seenJerseyNumbers[$jerseyKey])) {
                $validationErrors['jersey_number'] = 'Jersey number is duplicated inside this CSV upload for the selected club.';
            }
        }

        if ($validationErrors !== []) {
            $rowErrors[] = 'Row ' . $row['line'] . ': ' . implode(' ', array_values($validationErrors));
            continue;
        }

        $validatedRows[] = $payload;
        $seenNins[$nin] = true;
        if (($payload['jersey_number'] ?? null) !== null) {
            $seenJerseyNumbers[(string) $payload['jersey_number']] = true;
        }
    }

    if ($rowErrors !== []) {
        flash('bulk_errors', $rowErrors);
        flash('error', ['type' => 'danger', 'message' => 'Bulk player upload failed validation. Fix the listed rows and upload again.']);
        redirect('app/modules/players/bulk.php' . (!is_club_admin() && $clubId > 0 ? '?club_id=' . $clubId : ''));
    }

    db()->beginTransaction();

    try {
        $createdCount = 0;

        foreach ($validatedRows as $payload) {
            $payload['registration_number'] = $playerGenerateRegistrationNumber((int) $payload['club_id']);
            $playerId = $createPlayerRecord($payload, null);
            audit_log('create_player', 'players', $playerId, null, $payload + ['photo' => null, 'source' => 'bulk_csv']);
            $createdCount++;
        }

        audit_log('bulk_import_players', 'players', 0, null, ['club_id' => $clubId, 'rows_created' => $createdCount]);
        db()->commit();
    } catch (Throwable $exception) {
        if (db()->inTransaction()) {
            db()->rollBack();
        }

        flash('error', ['type' => 'danger', 'message' => 'Bulk player upload failed while saving records. No players were imported.']);
        redirect('app/modules/players/bulk.php' . (!is_club_admin() && $clubId > 0 ? '?club_id=' . $clubId : ''));
    }

    clear_old_input();
    flash('success', ['type' => 'success', 'message' => count($validatedRows) . ' players imported successfully. Passport and other documents can be uploaded later from each player profile.']);
    redirect('app/modules/players/index.php' . (!is_club_admin() ? '?club_id=' . $clubId : ''));
}

if ($action === 'update') {
    $playerId = (int) ($_POST['id'] ?? 0);
    $existingPlayer = $findPlayerOrAbort($playerId);
    remember_old_input($_POST);
    $errors = [];
    $payload = $validatePlayerPayload($_POST, $errors, $playerId, $existingPlayer);

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

    $photoPath = $existingPlayer['photo'];
    if (isset($_FILES['photo']) && ($_FILES['photo']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
        try {
            $photoPath = upload_file($_FILES['photo'], ['directory' => 'players', 'max_size' => 2 * 1024 * 1024]);
            delete_uploaded_file($existingPlayer['photo']);
        } catch (RuntimeException $exception) {
            flash('errors', ['photo' => $exception->getMessage()]);
            flash('error', ['type' => 'danger', 'message' => $exception->getMessage()]);
            redirect('app/modules/players/edit.php?id=' . $playerId);
        }
    }

    $payload['registration_number'] = $playerGenerateRegistrationNumber(
        (int) $payload['club_id'],
        $playerId,
        (string) ($existingPlayer['registration_number'] ?? '')
    );

    db_query(
        'UPDATE players
         SET club_id = :club_id,
             first_name = :first_name,
             last_name = :last_name,
             date_of_birth = :date_of_birth,
             nationality = :nationality,
             position = :position,
             jersey_number = :jersey_number,
             photo = :photo,
             nin = :nin,
             registration_number = :registration_number,
             medical_status = :medical_status,
             eligibility_status = :eligibility_status,
             transfer_status = :transfer_status,
             status = :status,
             updated_at = NOW()
         WHERE id = :id',
        $payload + ['photo' => $photoPath, 'id' => $playerId]
    );

    audit_log('update_player', 'players', $playerId, $existingPlayer, $payload + ['photo' => $photoPath]);
    clear_old_input();
    flash('success', ['type' => 'success', 'message' => 'Player updated successfully.']);
    redirect('app/modules/players/view.php?id=' . $playerId);
}

if ($action === 'set_eligibility_status') {
    if (!$canManagePlayerApproval()) {
        abort_request(403, 'Access denied', 'Only authorized league staff can approve or suspend players.');
    }

    $playerId = (int) ($_POST['id'] ?? 0);
    $existingPlayer = $findPlayerOrAbort($playerId);
    $eligibilityStatus = (string) ($_POST['eligibility_status'] ?? '');

    if (!in_array($eligibilityStatus, $playerEligibilityOptions(), true)) {
        flash('error', ['type' => 'danger', 'message' => 'Selected eligibility status is invalid.']);
        redirect('app/modules/players/view.php?id=' . $playerId);
    }

    db_query(
        'UPDATE players SET eligibility_status = :eligibility_status, updated_at = NOW() WHERE id = :id',
        ['eligibility_status' => $eligibilityStatus, 'id' => $playerId]
    );

    audit_log(
        'set_player_eligibility_status',
        'players',
        $playerId,
        ['eligibility_status' => $existingPlayer['eligibility_status']],
        ['eligibility_status' => $eligibilityStatus]
    );
    flash('success', ['type' => 'success', 'message' => 'Player eligibility status updated successfully.']);
    redirect('app/modules/players/view.php?id=' . $playerId);
}

if ($action === 'upload_document') {
    $playerId = (int) ($_POST['player_id'] ?? 0);
    $player = $findPlayerOrAbort($playerId);
    $errors = [];
    $payload = $validatePlayerDocumentPayload($_POST, $_FILES['document_file'] ?? [], $errors);

    if ($errors !== []) {
        flash('errors', $errors);
        flash('error', ['type' => 'danger', 'message' => 'Please correct the document upload form errors.']);
        redirect('app/modules/players/view.php?id=' . $playerId);
    }

    try {
        $filePath = upload_file($_FILES['document_file'], [
            'directory' => 'player-documents',
            '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', ['document_file' => $exception->getMessage()]);
        flash('error', ['type' => 'danger', 'message' => $exception->getMessage()]);
        redirect('app/modules/players/view.php?id=' . $playerId);
    }

    db_query(
        'INSERT INTO player_documents (player_id, document_type, title, file_path, uploaded_at)
         VALUES (:player_id, :document_type, :title, :file_path, NOW())',
        $payload + ['player_id' => $playerId, 'file_path' => $filePath]
    );

    $documentId = (int) db()->lastInsertId();
    audit_log('upload_player_document', 'players', $playerId, null, $payload + ['document_id' => $documentId, 'file_path' => $filePath, 'player_name' => $playerFullName($player)]);
    flash('success', ['type' => 'success', 'message' => 'Player document uploaded successfully.']);
    redirect('app/modules/players/view.php?id=' . $playerId);
}

if ($action === 'delete_document') {
    $documentId = (int) ($_POST['document_id'] ?? 0);
    $document = $findPlayerDocumentOrAbort($documentId);

    db_query('DELETE FROM player_documents WHERE id = :id', ['id' => $documentId]);
    delete_uploaded_file($document['file_path']);
    audit_log('delete_player_document', 'players', (int) $document['player_id'], $document, null);
    flash('success', ['type' => 'success', 'message' => 'Player document deleted successfully.']);
    redirect('app/modules/players/view.php?id=' . (int) $document['player_id']);
}

if ($action === 'delete') {
    $playerId = (int) ($_POST['id'] ?? 0);
    $existingPlayer = $findPlayerOrAbort($playerId);

    if ($playerHasDependencies($playerId)) {
        flash('error', ['type' => 'danger', 'message' => 'This player cannot be deleted while dependent records still exist.']);
        redirect('app/modules/players/delete.php?id=' . $playerId);
    }

    $documents = $playerDocuments($playerId);
    db_query('DELETE FROM players WHERE id = :id', ['id' => $playerId]);

    foreach ($documents as $document) {
        delete_uploaded_file($document['file_path']);
    }

    delete_uploaded_file($existingPlayer['photo']);
    audit_log('delete_player', 'players', $playerId, $existingPlayer, null);
    flash('success', ['type' => 'success', 'message' => 'Player deleted successfully.']);
    redirect('app/modules/players/index.php' . (!is_club_admin() ? '?club_id=' . (int) $existingPlayer['club_id'] : ''));
}

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