<?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) . '/modules/notifications/helpers.php';

function settings_module_boot(): void
{
    require_login();
    require_permission('manage_settings');
}

function settings_boolean_options(): array
{
    return [
        '0' => 'Disabled',
        '1' => 'Enabled',
    ];
}

function settings_season_mode_options(): array
{
    return [
        'single' => 'Single season mode',
        'multiple' => 'Multiple active seasons',
    ];
}

function settings_match_report_mode_options(): array
{
    return [
        'published' => 'Auto-publish verified match reports',
        'draft' => 'Save verified match reports as drafts',
    ];
}

function editable_settings_schema(): array
{
    return [
        'branding' => [
            'title' => 'Branding and contact',
            'fields' => [
                'league_name' => ['label' => 'League name', 'type' => 'text', 'required' => true, 'default' => 'JLFC - Jalingo Local Football Council'],
                'league_short_name' => ['label' => 'League short name', 'type' => 'text', 'required' => true, 'default' => 'JLFC'],
                'league_logo' => ['label' => 'League logo', 'type' => 'file', 'required' => false, 'default' => '', 'accept' => 'image/*'],
                'organization_name' => ['label' => 'Organization name', 'type' => 'text', 'required' => true, 'default' => 'Jalingo Local Football Council'],
                'contact_email' => ['label' => 'Contact email', 'type' => 'email', 'required' => true, 'default' => 'admin@jlfc.com'],
                'contact_phone' => ['label' => 'Contact phone', 'type' => 'text', 'required' => true, 'default' => '+2340000000000'],
                'primary_color' => ['label' => 'Primary color', 'type' => 'text', 'required' => true, 'default' => 'dark green'],
                'accent_color' => ['label' => 'Accent color', 'type' => 'text', 'required' => true, 'default' => 'gold'],
            ],
        ],
        'competition' => [
            'title' => 'Competition defaults',
            'fields' => [
                'season_mode' => ['label' => 'Season mode', 'type' => 'select', 'options' => settings_season_mode_options(), 'required' => true, 'default' => 'single'],
                'points_win' => ['label' => 'Points for win', 'type' => 'number', 'required' => true, 'default' => '3'],
                'points_draw' => ['label' => 'Points for draw', 'type' => 'number', 'required' => true, 'default' => '1'],
                'points_loss' => ['label' => 'Points for loss', 'type' => 'number', 'required' => true, 'default' => '0'],
            ],
        ],
        'discipline' => [
            'title' => 'Discipline and protests',
            'fields' => [
                'yellow_card_suspension_threshold' => ['label' => 'Yellow card threshold', 'type' => 'number', 'required' => true, 'default' => '5'],
                'red_card_suspension_default' => ['label' => 'Red card suspension default', 'type' => 'number', 'required' => true, 'default' => '1'],
                'protest_deadline_hours' => ['label' => 'Protest deadline hours', 'type' => 'number', 'required' => true, 'default' => '48'],
            ],
        ],
        'workflow' => [
            'title' => 'Workflow toggles',
            'fields' => [
                'require_payment_before_approval' => ['label' => 'Require payment before approval', 'type' => 'select', 'options' => settings_boolean_options(), 'required' => true, 'default' => '0'],
                'enable_public_registration' => ['label' => 'Enable public registration', 'type' => 'select', 'options' => settings_boolean_options(), 'required' => true, 'default' => '0'],
                'enable_multiple_active_seasons' => ['label' => 'Allow multiple active seasons', 'type' => 'select', 'options' => settings_boolean_options(), 'required' => true, 'default' => '0'],
                'enable_match_update_drafts' => ['label' => 'Create draft match updates', 'type' => 'select', 'options' => settings_boolean_options(), 'required' => true, 'default' => '1'],
                'verified_match_report_mode' => ['label' => 'Verified match report mode', 'type' => 'select', 'options' => settings_match_report_mode_options(), 'required' => true, 'default' => 'published'],
            ],
        ],
        'notifications' => [
            'title' => 'Web push notifications',
            'fields' => [
                'enable_web_push_notifications' => ['label' => 'Enable web push notifications', 'type' => 'select', 'options' => settings_boolean_options(), 'required' => true, 'default' => '1'],
                'web_push_vapid_subject' => ['label' => 'VAPID subject', 'type' => 'text', 'required' => true, 'default' => ''],
                'web_push_vapid_public_key' => ['label' => 'VAPID public key', 'type' => 'text', 'required' => true, 'default' => ''],
                'web_push_vapid_private_key' => ['label' => 'VAPID private key', 'type' => 'text', 'required' => true, 'default' => ''],
            ],
        ],
    ];
}

function settings_form_values(): array
{
    web_push_ensure_settings();

    $values = [];
    foreach (editable_settings_schema() as $section) {
        foreach ($section['fields'] as $key => $meta) {
            if ($key === 'enable_web_push_notifications' || str_starts_with($key, 'web_push_')) {
                $values[$key] = web_push_setting($key, (string) ($meta['default'] ?? ''));
                continue;
            }

            $values[$key] = site_setting($key, $meta['default'] ?? '');
        }
    }

    return $values;
}

function validate_settings_payload(array $data, array &$errors): array
{
    $schema = editable_settings_schema();
    $required = [];
    $normalized = [];

    foreach ($schema as $section) {
        foreach ($section['fields'] as $key => $meta) {
            if (!empty($meta['required'])) {
                $required[$key] = $meta['label'];
            }

            if (($meta['type'] ?? 'text') === 'file') {
                $normalized[$key] = (string) site_setting($key, (string) ($meta['default'] ?? ''));
                continue;
            }

            $normalized[$key] = trim((string) ($data[$key] ?? ''));
        }
    }

    validate_required($data, $required, $errors);
    validate_email_field($data, 'contact_email', 'Contact email', $errors);
    validate_phone_field($data, 'contact_phone', 'Contact phone', $errors);

    validate_in_array_field($data, 'season_mode', array_keys(settings_season_mode_options()), 'Season mode', $errors);
    validate_in_array_field($data, 'require_payment_before_approval', array_keys(settings_boolean_options()), 'Require payment before approval', $errors);
    validate_in_array_field($data, 'enable_public_registration', array_keys(settings_boolean_options()), 'Enable public registration', $errors);
    validate_in_array_field($data, 'enable_multiple_active_seasons', array_keys(settings_boolean_options()), 'Allow multiple active seasons', $errors);
    validate_in_array_field($data, 'enable_match_update_drafts', array_keys(settings_boolean_options()), 'Create draft match updates', $errors);
    validate_in_array_field($data, 'enable_web_push_notifications', array_keys(settings_boolean_options()), 'Enable web push notifications', $errors);
    validate_in_array_field($data, 'verified_match_report_mode', array_keys(settings_match_report_mode_options()), 'Verified match report mode', $errors);

    validate_numeric_min($data, 'points_win', 'Points for win', 0, $errors);
    validate_numeric_min($data, 'points_draw', 'Points for draw', 0, $errors);
    validate_numeric_min($data, 'points_loss', 'Points for loss', 0, $errors);
    validate_numeric_min($data, 'yellow_card_suspension_threshold', 'Yellow card threshold', 1, $errors);
    validate_numeric_min($data, 'red_card_suspension_default', 'Red card suspension default', 1, $errors);
    validate_numeric_min($data, 'protest_deadline_hours', 'Protest deadline hours', 1, $errors);

    if (($normalized['enable_web_push_notifications'] ?? '1') === '1') {
        if (($normalized['web_push_vapid_subject'] ?? '') === '') {
            $errors['web_push_vapid_subject'] = 'VAPID subject is required when web push notifications are enabled.';
        }

        if (($normalized['web_push_vapid_public_key'] ?? '') === '') {
            $errors['web_push_vapid_public_key'] = 'VAPID public key is required when web push notifications are enabled.';
        }

        if (($normalized['web_push_vapid_private_key'] ?? '') === '') {
            $errors['web_push_vapid_private_key'] = 'VAPID private key is required when web push notifications are enabled.';
        }
    }

    return $normalized;
}
