<?php

declare(strict_types=1);

require_once dirname(__DIR__, 2) . '/core/auth.php';
require_once dirname(__DIR__, 2) . '/core/csrf.php';
require_once dirname(__DIR__, 2) . '/core/validation.php';
require_once dirname(__DIR__, 2) . '/core/audit.php';
require_once dirname(__DIR__, 2) . '/core/upload.php';

function club_module_boot(): void
{
    require_login();
    require_permission('manage_clubs');
}

function club_status_options(): array
{
    return ['active', 'inactive', 'suspended'];
}

function club_license_options(): array
{
    return ['pending', 'approved', 'rejected', 'suspended'];
}

function club_payment_options(): array
{
    return ['unpaid', 'partial', 'paid'];
}

function can_create_club(): bool
{
    return !is_club_admin();
}

function club_is_fixture_eligible(array $club): bool
{
    return ($club['license_status'] ?? '') === 'approved' && ($club['status'] ?? '') === 'active';
}

function club_list(): array
{
    if (is_club_admin()) {
        $clubId = user_club_id();

        if ($clubId === null) {
            return [];
        }

        return db_fetch_all(
            'SELECT c.*, COUNT(DISTINCT cs.id) AS staff_count, COUNT(DISTINCT p.id) AS player_count
             FROM clubs c
             LEFT JOIN club_staff cs ON cs.club_id = c.id
             LEFT JOIN players p ON p.club_id = c.id
             WHERE c.id = :club_id
             GROUP BY c.id',
            ['club_id' => $clubId]
        );
    }

    return db_fetch_all(
        'SELECT c.*, COUNT(DISTINCT cs.id) AS staff_count, COUNT(DISTINCT p.id) AS player_count
         FROM clubs c
         LEFT JOIN club_staff cs ON cs.club_id = c.id
         LEFT JOIN players p ON p.club_id = c.id
         GROUP BY c.id
         ORDER BY c.created_at DESC, c.id DESC'
    );
}

function club_options(): array
{
    if (is_club_admin()) {
        $club = get_club_by_id((int) user_club_id());
        return $club ? [$club] : [];
    }

    return db_fetch_all('SELECT id, name, short_name, status FROM clubs ORDER BY name ASC');
}

function get_club_by_id(int $clubId): ?array
{
    return db_fetch_one('SELECT * FROM clubs WHERE id = :id LIMIT 1', ['id' => $clubId]);
}

function find_club_or_abort(int $clubId): array
{
    $club = get_club_by_id($clubId);

    if ($club === null) {
        abort_request(404, 'Club not found', 'The requested club record does not exist.');
    }

    require_club_scope((int) $club['id']);

    return $club;
}

function club_has_dependencies(int $clubId): bool
{
    return (int) db_fetch_value(
        'SELECT (
            (SELECT COUNT(*) FROM club_staff WHERE club_id = :staff_club_id) +
            (SELECT COUNT(*) FROM players WHERE club_id = :player_club_id) +
            (SELECT COUNT(*) FROM fixtures WHERE home_club_id = :home_fixture_club_id OR away_club_id = :away_fixture_club_id) +
            (SELECT COUNT(*) FROM match_events WHERE club_id = :match_event_club_id)
        )',
        [
            'staff_club_id' => $clubId,
            'player_club_id' => $clubId,
            'home_fixture_club_id' => $clubId,
            'away_fixture_club_id' => $clubId,
            'match_event_club_id' => $clubId,
        ],
        0
    ) > 0;
}

function validate_club_payload(array $data, array &$errors, ?int $clubId = null, ?array $existingClub = null): array
{
    validate_required($data, [
        'name' => 'Club name',
        'short_name' => 'Short name',
    ], $errors);
    validate_email_field($data, 'email', 'Email', $errors);
    validate_phone_field($data, 'phone', 'Phone', $errors);

    if (!is_club_admin()) {
        validate_in_array_field($data, 'license_status', club_license_options(), 'License status', $errors);
        validate_in_array_field($data, 'payment_status', club_payment_options(), 'Payment status', $errors);
        validate_in_array_field($data, 'status', club_status_options(), 'Status', $errors);
    }

    $foundedYear = trim((string) ($data['founded_year'] ?? ''));
    if ($foundedYear !== '' && (!ctype_digit($foundedYear) || (int) $foundedYear < 1800 || (int) $foundedYear > (int) date('Y'))) {
        $errors['founded_year'] = 'Founded year is invalid.';
    }

    $normalized = [
        'name' => trim((string) ($data['name'] ?? '')),
        'short_name' => strtoupper(trim((string) ($data['short_name'] ?? ''))),
        'founded_year' => $foundedYear === '' ? null : (int) $foundedYear,
        'stadium_name' => trim((string) ($data['stadium_name'] ?? '')),
        'contact_person' => trim((string) ($data['contact_person'] ?? '')),
        'phone' => trim((string) ($data['phone'] ?? '')),
        'email' => strtolower(trim((string) ($data['email'] ?? ''))),
        'license_status' => is_club_admin() ? ($existingClub['license_status'] ?? 'pending') : (string) ($data['license_status'] ?? 'pending'),
        'payment_status' => is_club_admin() ? ($existingClub['payment_status'] ?? 'unpaid') : (string) ($data['payment_status'] ?? 'unpaid'),
        'status' => is_club_admin() ? ($existingClub['status'] ?? 'active') : (string) ($data['status'] ?? 'active'),
    ];

    if ($normalized['short_name'] !== '' && !preg_match('/^[A-Z0-9-]{2,25}$/', $normalized['short_name'])) {
        $errors['short_name'] = 'Short name may contain only letters, numbers, and hyphens.';
    }

    if ($normalized['name'] !== '' && duplicate_exists('clubs', 'name', $normalized['name'], $clubId)) {
        $errors['name'] = 'Club name already exists.';
    }

    if ($normalized['short_name'] !== '' && duplicate_exists('clubs', 'short_name', $normalized['short_name'], $clubId)) {
        $errors['short_name'] = 'Short name already exists.';
    }

    return $normalized;
}

function club_badge_class(string $status): string
{
    return match ($status) {
        'active', 'approved', 'paid' => 'badge-soft-success',
        'partial', 'pending', 'inactive' => 'text-bg-light',
        'rejected', 'suspended', 'unpaid' => 'badge-soft-danger',
        default => 'text-bg-light',
    };
}
