{% extends request.ajax ? 'layout_blank.html.twig' : 'layout_default.html.twig' %}

{% block meta_title %}{{ 'Update FOSSBilling'|trans }}{% endblock %}
{% set active_menu = 'system' %}

{% block content %}
    {% set update_info = admin.system_update_info %}
    {% set isPreviewBranch = update_info['branch'] == 'preview' %}
    {% set updateAvailable = admin.system_update_available %}
    {% set updateCandidateAvailable = updateAvailable or isPreviewBranch %}
    {% set phpVersionSupported = update_info['php_version_supported'] is defined ? update_info['php_version_supported'] : true %}
    {% set minimumPhpVersion = update_info['minimum_php_version']|default('unknown') %}
    {% set currentPhpVersion = update_info['current_php_version']|default(constant('PHP_VERSION')) %}
    {% set readiness = update_info['readiness']|default({}) %}
    {% set updateReady = readiness['can_update'] is defined ? readiness['can_update'] : true %}
    {% set readinessIssues = readiness['issues'] is defined ? readiness['issues'] : [] %}
    {% set previewCompareUrl = 'https://github.com/FOSSBilling/FOSSBilling/compare/' ~ FOSSBillingVersion ~ '...main' %}
    {% set canInstallUpdate = updateCandidateAvailable and phpVersionSupported and updateReady %}
    {% set behindOnPatches = admin.system_is_behind_on_patches %}
    {% set updateType = update_info['update_type']|default(0) + 0 %}
    {% if isPreviewBranch %}
        {% set updateButtonLabel = 'Install Latest Preview Build'|trans %}
        {% set updateButtonClass = 'btn-primary' %}
        {% set updateConfirmTitle = 'Install latest preview build?'|trans %}
        {% set updateModalType = 'confirm' %}
        {% set updateModalContent = 'Preview builds may contain unreleased changes, regressions, or incomplete migrations. Back up your files and database, and avoid using this on production installations unless you are prepared to troubleshoot issues.'|trans %}
        {% set updateModalButton = 'Install Preview Build'|trans %}
    {% else %}
        {% set updateButtonLabel = 'Update FOSSBilling'|trans %}
        {% set updateButtonClass = 'btn-primary' %}
        {% set updateConfirmTitle = 'Update FOSSBilling?'|trans %}
        {% set updateModalType = 'confirm' %}
        {% set updateModalContent = 'Before continuing, back up your FOSSBilling files and database. This will download and install the latest available FOSSBilling release, enable maintenance mode, clear the cache, and log you out of the admin area. After logging back in, you will be asked to finalize the update.'|trans %}
        {% set updateModalButton = 'Update FOSSBilling'|trans %}
    {% endif %}
    <div class="row row-cards">
        <div class="col-12">
            <div class="card">
                <div class="card-header">
                    <div class="d-flex flex-wrap align-items-start justify-content-between gap-2 w-100">
                        <div>
                            <h3 class="card-title">{{ 'FOSSBilling Updates'|trans }}</h3>
                            <p class="card-subtitle">{{ isPreviewBranch ? 'Install preview builds and review update status.'|trans : 'Review release notes, check for updates, and install available platform updates.'|trans }}</p>
                        </div>
                        {% if isPreviewBranch %}
                            <span class="badge badge-outline text-warning">{{ 'Preview Branch'|trans }}</span>
                        {% endif %}
                    </div>
                </div>
                <div class="card-body">
                    {% if updateCandidateAvailable %}
                        {% if not phpVersionSupported %}
                            <div class="alert alert-danger" role="alert">
                                <strong class="me-1">{{ 'PHP version not supported:'|trans }}</strong>{{ 'This update requires PHP %required%, but this server is running PHP %current%.'|trans({'%required%': minimumPhpVersion, '%current%': currentPhpVersion}) }}
                            </div>
                        {% endif %}
                        {% if not updateReady %}
                            <div class="alert alert-danger" role="alert">
                                <strong class="me-1">{{ 'Update cannot start:'|trans }}</strong>{{ 'FOSSBilling does not have sufficient filesystem permissions to perform the update on this server. Please review the issues below and resolve them before attempting the update again.'|trans }}
                                <ul class="mt-2 mb-0">
                                    {% for issue in readinessIssues %}
                                        <li><code>{{ issue.path }}</code> &mdash; {{ issue.message }}</li>
                                    {% endfor %}
                                </ul>
                            </div>
                        {% endif %}
                        {% if isPreviewBranch %}
                            <h4 class="mb-2">{{ 'Preview Build Updates'|trans }}</h4>
                            <div class="alert alert-warning" role="alert">
                                {{ 'Preview builds track unreleased development changes and may be unstable. It is not recommended to use them in production environments.'|trans }}
                            </div>
                            <p class="text-secondary mb-0">
                                {{ 'Release notes are not available for preview builds.'|trans }}
                                <a class="ms-1" href="{{ previewCompareUrl }}" target="_blank" rel="noopener noreferrer">{{ 'View GitHub Comparison'|trans }}</a>
                            </p>
                        {% else %}
                            <h4 class="mb-0">{{ 'Update Release Notes'|trans }} ({{ FOSSBillingVersion }} => {{ update_info['version'] }})</h4>
                            {% if updateType == 2 %}
                                <div class="alert alert-warning" role="alert">
                                    <strong class="me-1">{{ 'Important:'|trans }}</strong>{{ 'This update is considered to be a major update, you should check the release notes for any breaking changes.'|trans }}
                                </div>
                            {% endif %}
                            {% if updateType == 1 %}
                                <div class="alert alert-info" role="alert">
                                    <strong class="me-1">{{ 'Information:'|trans }}</strong>{{ 'This update is considered to be a minor update, there are low chances of incompatibilities.'|trans }}
                                </div>
                            {% endif %}
                            {{ (update_info['release_notes'] ?? '')|markdown_to_html }}
                        {% endif %}
                    {% else %}
                        <h2 class="card-title">{{ 'There Is No Update Available'|trans }}</h2>
                        <p>{{ 'You appear to be running the latest version of FOSSBilling, so no action is needed at the moment. If you think this is a mistake, you may use the button below to check again.'|trans }}</p>
                    {% endif %}
                </div>
                <div class="card-footer">
                    {% if canInstallUpdate %}
                        <div class="form-check mb-3">
                            <input class="form-check-input" type="checkbox" id="update-backup-acknowledgement" data-update-backup-acknowledgement>
                            <label class="form-check-label" for="update-backup-acknowledgement">
                                {{ 'I have backed up the FOSSBilling files and database.'|trans }}
                            </label>
                            <div class="form-text">{{ 'The update button is enabled only after confirming that backups are available.'|trans }}</div>
                        </div>
                    {% endif %}
                    <div class="d-flex flex-wrap gap-2">
                        {% if canInstallUpdate %}
                            <a class="btn {{ updateButtonClass }} disabled" href="#" aria-disabled="true" data-update-requires-backup data-update-href="{{ 'system/update_core'|api_url }}"
                                {{ fb_api_link({
                                    modal: {type: updateModalType, title: updateConfirmTitle, content: updateModalContent, button: updateModalButton},
                                    reload: true,
                                    timeoutMs: 300000,
                                    timeoutMessage: 'The update request took longer than expected. The server may still be finishing the update. Wait a minute before refreshing or trying again.'|trans,
                                    preventNavigation: true,
                                    loading: {
                                        target: '#update-progress',
                                        button: 'Updating FOSSBilling...'|trans,
                                        message: 'The update is running and can take several minutes. Keep this tab open and do not retry unless an error is shown.'|trans
                                    }
                                }) }}>
                                <svg class="icon">
                                    <use xlink:href="#download" />
                                </svg>
                                {{ updateButtonLabel }}
                            </a>
                        {% else %}
                            <a class="btn btn-secondary disabled" aria-disabled="true">
                                <svg class="icon">
                                    <use xlink:href="#download" />
                                </svg>
                                {{ updateButtonLabel }}
                            </a>
                        {% endif %}
                        {% if not isPreviewBranch %}
                            <a class="btn btn-outline-secondary" href="{{ 'system/recheck_update'|api_url }}" {{ fb_api_link({ reload: true }) }}>
                                <svg class="icon">
                                    <use xlink:href="#refresh" />
                                </svg>
                                {{ 'Check for Updates'|trans }}
                            </a>
                        {% endif %}
                    </div>
                    <div id="update-progress"></div>
                    {% if not isPreviewBranch %}
                        <div class="d-flex flex-wrap gap-4 mt-3 text-secondary small">
                            <div>{{ 'Last update check:'|trans }} {{ update_info['last_check']|format_datetime() }}.</div>
                            <div>{{ 'Next update check:'|trans }} {{ update_info['next_check']|format_datetime() }}.</div>
                        </div>
                    {% endif %}
                </div>
            </div>
        </div>

        <div class="col-12">
            <div class="card">
                <div class="card-header">
                    <div class="d-flex flex-wrap align-items-start justify-content-between gap-2 w-100">
                        <div>
                            <h3 class="card-title">{{ 'Database & Configuration Patches'|trans }}</h3>
                            <p class="card-subtitle">{{ 'Keep database structure and settings aligned with the installed FOSSBilling version.'|trans }}</p>
                        </div>
                        <span class="badge {{ behindOnPatches ? 'badge-outline text-warning' : 'badge-outline text-success' }}">{{ behindOnPatches ? 'Pending'|trans : 'Up to Date'|trans }}</span>
                    </div>
                </div>
                <div class="card-body">
                    {% if behindOnPatches %}
                        <div class="alert alert-warning" role="alert">
                            <strong class="me-1">{{ 'Database Patches Pending:'|trans }}</strong>{{ 'Apply the pending database patches to keep this installation aligned with the installed FOSSBilling files.'|trans }}
                        </div>
                    {% endif %}
                    <p>{{ 'Database patches are small migrations that update FOSSBilling database tables and settings after the application files change.'|trans }}</p>
                    <p class="text-secondary mb-0">{{ 'Update patches are automatically run after FOSSBilling updates. Use the manual action here only when FOSSBilling reports pending patches or when troubleshooting update issues.'|trans }}</p>
                </div>
                <div class="card-footer">
                    <div class="d-flex flex-wrap gap-2">
                        <a class="btn {{ behindOnPatches ? 'btn-success' : 'btn-secondary' }}" href="{{ 'system/manual_update'|api_url }}"
                            {{ fb_api_link({
                                message: 'Patches Applied and Configuration Updated'|trans,
                                modal: {type: 'confirm', title: 'Are you sure?'|trans},
                                timeoutMs: 180000,
                                timeoutMessage: 'Applying patches took longer than expected. The server may still be finishing the patching process. Wait a minute before refreshing or trying again.'|trans,
                                preventNavigation: true,
                                loading: {
                                    target: '#patch-progress',
                                    button: 'Applying patches...'|trans,
                                    message: 'Database and configuration patches are being applied. Keep this tab open until the request completes.'|trans
                                }
                            }) }}>
                            <svg class="icon">
                                <use xlink:href="#cog-play" />
                            </svg>
                            {{ 'Apply Patches & Update Configuration'|trans }}
                        </a>
                    </div>
                    <div id="patch-progress"></div>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

{% block js %}
<script>
    document.addEventListener('DOMContentLoaded', () => {
        const acknowledgement = document.querySelector('[data-update-backup-acknowledgement]');
        const updateButton = document.querySelector('[data-update-requires-backup]');

        if (!acknowledgement || !updateButton) {
            return;
        }

        const updateButtonState = () => {
            const disabled = !acknowledgement.checked;
            updateButton.classList.toggle('disabled', disabled);
            updateButton.setAttribute('aria-disabled', disabled ? 'true' : 'false');
            updateButton.setAttribute('href', disabled ? '#' : (updateButton.dataset.updateHref ?? '#'));
        };

        acknowledgement.addEventListener('change', updateButtonState);
        updateButtonState();
    });
</script>
{% endblock %}
