{{define "backups_apps"}}
{{template "layout_start" .}}

<div class="page-header">
    <h2>Biztonsági mentés — Alkalmazások</h2>
    <span class="domain-badge">{{.Domain}}</span>
</div>

{{template "backups_flash" .}}
{{template "restore_banner" .}}

{{if not .Backup}}
{{template "backups_empty" .}}
{{else}}

<h3 class="backup-tier-divider">Alkalmazás-mentések (adatbázis + konfiguráció)</h3>
<p class="form-hint" style="margin:-0.25rem 0 1rem">Az egyes alkalmazások részletes, granulált mentése — adatbázis-kiírások, beállítások és alkalmazás-fájlok. A fenti teljes mentéstől függetlenül, alkalmazásonként visszaállítható.</p>

<!-- Section 2: Schedule -->
<div class="schedule-card">
    <h3>Ütemezés</h3>
    <div class="schedule-rows">
        <div class="schedule-row">
            <span class="schedule-task">Adatbázis mentés</span>
            <span class="schedule-time">{{.Backup.DBDumpSchedule}}</span>
            <span class="schedule-next">Következő: {{nextRunLabel .Backup.NextDBDump}}</span>
        </div>
    </div>
    <div class="schedule-summary">
        {{if .Backup.LastDBDump}}
            <div class="schedule-summary-row">
                <span>Utolsó adatbázis mentés:</span>
                <span class="schedule-summary-value">{{fmtTime .Backup.LastDBDump.LastRun}} ({{timeAgo .Backup.LastDBDump.LastRun}})</span>
            </div>
        {{else}}
            <div class="schedule-summary-row">
                <span>Utolsó adatbázis mentés:</span>
                <span class="schedule-summary-value relative-time">Még nem futott</span>
            </div>
        {{end}}
    </div>
    <div class="schedule-actions">
        <button class="btn btn-sm btn-primary" onclick="triggerBackupFromPage()" id="backup-page-btn"
            {{if .Backup.Running}}disabled{{end}}>
            {{if .Backup.Running}}Mentés folyamatban...{{else}}Mentés most{{end}}
        </button>
    </div>
</div>

<!-- Section 3: Databases -->
<div class="backup-section-card">
    <h3>Adatbázisok</h3>
    {{if or .Backup.DumpFiles .Backup.DiscoveredDBs}}
    <div class="backup-table-wrap">
        <table class="db-table">
            <thead>
                <tr>
                    <th>Alkalmazás</th>
                    <th>Típus</th>
                    <th>Méret</th>
                    <th>Utolsó</th>
                    <th>Érvényesítés</th>
                    <th>Állapot</th>
                </tr>
            </thead>
            <tbody>
                {{if .Backup.LastDBDump}}
                    {{range .Backup.LastDBDump.Results}}
                    <tr>
                        <td>{{.DB.StackName}}</td>
                        <td><span class="db-type-badge db-type-{{.DB.DBType}}">{{dbTypeLabel .DB.DBType}}</span></td>
                        <td class="mono">{{if .Error}}–{{else}}{{fmtBytes .Size}}{{end}}</td>
                        <td class="mono">{{if .Error}}–{{else}}{{fmtTimeShort $.Backup.LastDBDump.LastRun}}{{end}}</td>
                        <td>
                            {{if .Error}}
                                <span class="validation-badge validation-na">–</span>
                            {{else if .Validation.Valid}}
                                <span class="validation-badge validation-ok">{{.Validation.TableCount}} tábla</span>
                            {{else if .Validation.Error}}
                                <span class="validation-badge validation-fail" title="{{.Validation.Error}}">Hiba</span>
                            {{else}}
                                <span class="validation-badge validation-na" title="Az érvényesítés nem futott le">–</span>
                            {{end}}
                        </td>
                        <td>
                            {{if .Error}}
                                <span class="validation-badge validation-fail" title="{{.Error}}">Hiba</span>
                            {{else}}
                                <span class="validation-badge validation-ok">OK</span>
                            {{end}}
                        </td>
                    </tr>
                    {{end}}
                {{else}}
                    {{range .Backup.DumpFiles}}
                    <tr>
                        <td>{{.StackName}}</td>
                        <td><span class="db-type-badge db-type-{{.DBType}}">{{dbTypeLabel .DBType}}</span></td>
                        <td class="mono">{{fmtBytes .Size}}</td>
                        <td class="mono">{{fmtTimeShort .ModTime}}</td>
                        <td>
                            {{if .Validation.Valid}}
                                <span class="validation-badge validation-ok">{{.Validation.TableCount}} tábla</span>
                            {{else if .Validation.Error}}
                                <span class="validation-badge validation-fail" title="{{.Validation.Error}}">Hiba</span>
                            {{else}}
                                <span class="validation-badge validation-na">–</span>
                            {{end}}
                        </td>
                        <td><span class="validation-badge validation-ok">OK</span></td>
                    </tr>
                    {{end}}
                {{end}}
            </tbody>
        </table>
    </div>
    {{else if eq .DBSectionState "pending"}}
    <div class="backup-table-empty">Még nem készült adatbázis-mentés — az első ütemezett mentés éjjel fut le.</div>
    {{else}}
    <div class="backup-table-empty">A telepített alkalmazások beágyazott adatbázist használnak (pl. SQLite) — adatbázisuk a fájl- és kötetmentés része, külön adatbázis-kiírás nem szükséges.</div>
    {{end}}
</div>

<!-- Section 4: Unified per-app backup status -->
{{if .Backup.AppDataInfo}}
<div class="backup-section-card">
    <h3>Alkalmazások mentési állapota</h3>

    {{if .NoUserDataBackupWarning}}
    <div class="alert alert-error" style="margin-bottom:1.5rem">
        <strong>Felhasználói adatokról nincs biztonsági mentés.</strong><br>
        A szerveren tárolt fotók, dokumentumok és egyéb fájlok jelenleg csak egy példányban léteznek.
        Külső meghajtó csatlakoztatásával biztonsági másolat készíthető a 3-2-1 szabály szerint.
        <a href="/settings" style="color:inherit;text-decoration:underline">Meghajtó beállítása →</a>
    </div>
    {{end}}

    {{range .AppBackupRows}}
    <div class="app-backup-row" data-status="{{.Status}}">
        <!-- Aligned to the shared app-row grammar (icon + name left, status + chevron right);
             the expander behavior is untouched — this header is the one allowlisted aligned
             copy in scripts/app_row_dedup_gate.py, NOT a partial render (it owns the toggle).
             The icon chain matches app_row.html: SVG -> PNG -> /static/app-placeholder.svg, so a
             logo-less app shows the placeholder here too instead of a hidden dead-end (v0.163.1). -->
        <div class="app-backup-row-header" onclick="toggleBackupDetail(this)">
            <img class="app-row-icon" src="{{logoURL .Slug}}" alt="" data-fallback="/static/app-placeholder.svg"
                 onerror="if(!this.dataset.step){this.dataset.step='1';this.src='{{logoPNGURL .Slug}}';}else if(this.dataset.fallback&&this.dataset.step==='1'){this.dataset.step='2';this.src=this.dataset.fallback;}else{this.onerror=null;this.style.visibility='hidden';}">
            <span class="app-backup-row-name">{{.DisplayName}}</span>
            <div class="app-backup-row-meta">
                {{if .DriveDisconnected}}
                    <span class="tag tag-warn">Meghajtó leválasztva</span>
                {{else if .HasHDDData}}
                    {{if .StorageLabel}}<span class="meta-badge meta-badge-storage">{{.StorageLabel}}</span>{{end}}
                    <span class="mono app-backup-size" style="font-size:.8rem">{{.HDDSizeHuman}}</span>
                {{else if .HasVolumeData}}
                    <span class="meta-badge">Konfig{{if .HasDB}} + DB{{end}} + Adatok</span>
                {{else}}
                    <span class="meta-badge">Konfig{{if .HasDB}} + DB{{end}}</span>
                {{end}}
                <span class="status-dot status-{{.Status}}" title="{{.StatusText}}"></span>
            </div>
            <span class="expand-icon">▶</span>
        </div>
        <div class="app-backup-row-detail" style="display:none">
            <div class="backup-layers">
                <!-- Tier 1: Nightly backup (mandatory, same drive) -->
                <div class="backup-layer-row">
                    <span class="tier-label">1. mentés</span>
                    <span class="layer-badge">Auto</span>
                    <span class="tier-location">helyi</span>
                    {{if .Tier1LastRun}}
                    <span class="layer-last">Utolsó: {{timeAgoStr .Tier1LastRun}}
                        {{if eq .Tier1LastStatus "ok"}}<span class="text-ok"><svg class="ico ico-sm"><use href="#i-check"/></svg></span>
                        {{else if eq .Tier1LastStatus "error"}}<span class="text-error"><svg class="ico ico-sm"><use href="#i-x"/></svg></span>{{end}}
                    </span>
                    {{end}}
                    <span class="tier-contents">{{.BackupContents}}</span>
                    {{if and .HasDB (eq .Tier1DBStatus "error")}}
                    <span class="text-error" style="font-size:.8rem"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> DB dump hiba</span>
                    {{end}}
                </div>
                <!-- Tier 2: Cross-drive backup (opt-in, different device) -->
                <div class="backup-layer-row">
                    <span class="tier-label">2. mentés</span>
                    {{if .Tier2UserDisabled}}
                        <span class="layer-unconfigured">2. mentés kikapcsolva</span>
                        <div class="layer-actions">
                            <a href="/stacks/{{.StackName}}/backup" class="btn btn-xs btn-outline">Beállítás</a>
                        </div>
                    {{else if and .Tier2Configured .Tier2DestDisconnected}}
                        <span class="layer-method" style="opacity:.6">rsync</span>
                        <span class="layer-dest" style="opacity:.6">→ {{.Tier2Dest}}</span>
                        <span class="tag tag-warn">Cél meghajtó leválasztva</span>
                        {{if .Tier2LastRun}}
                        <span class="layer-last" style="opacity:.6">Utolsó: {{timeAgoStr .Tier2LastRun}}</span>
                        {{end}}
                        <span class="tier-contents" style="opacity:.6">{{.BackupContents}}</span>
                        <div class="layer-actions">
                            <a href="/stacks/{{.StackName}}/backup" class="btn btn-xs btn-outline">Beállítás</a>
                        </div>
                    {{else if and .Tier2Configured .Tier2DestInactive}}
                        <span class="layer-method" style="opacity:.6">rsync</span>
                        <span class="layer-dest" style="opacity:.6">→ {{.Tier2Dest}}</span>
                        <span class="tag tag-warn">Cél meghajtó inaktív</span>
                        {{if .Tier2LastRun}}
                        <span class="layer-last" style="opacity:.6">Utolsó: {{timeAgoStr .Tier2LastRun}}</span>
                        {{end}}
                        <span class="tier-contents" style="opacity:.6">{{.BackupContents}}</span>
                        <div class="layer-actions">
                            <a href="/stacks/{{.StackName}}/backup" class="btn btn-xs btn-outline">Beállítás</a>
                        </div>
                    {{else if .Tier2Configured}}
                        <span class="layer-method">rsync</span>
                        <span class="layer-dest">→ {{.Tier2Dest}}</span>
                        <span class="layer-schedule">{{.Tier2Schedule}}</span>
                        {{if .Tier2LastRun}}
                        <span class="layer-last">Utolsó: {{timeAgoStr .Tier2LastRun}}
                            <span class="{{if eq .Tier2LastStatus "ok"}}text-ok{{else if eq .Tier2LastStatus "error"}}text-error{{else if eq .Tier2LastStatus "running"}}text-muted{{end}}">
                                {{.Tier2StatusBadge}}
                            </span>
                        </span>
                        {{end}}
                        {{if .Tier2SizeHuman}}<span class="tier-size">{{.Tier2SizeHuman}}</span>{{end}}
                        {{if .Tier2LastWarning}}<span class="layer-reason" style="color:var(--warn);opacity:.9">{{.Tier2LastWarning}}</span>{{end}}
                        <span class="tier-contents">{{.BackupContents}}</span>
                        <span class="tier-browsable" title="A mentés böngészhető fájlrendszerben"><svg class="ico ico-sm"><use href="#i-file-text"/></svg></span>
                        <div class="layer-actions">
                            {{if .Tier2LastRun}}
                            <form method="POST" action="/backup/tier2/restore" style="display:inline">{{$.CSRFField}}
                                <input type="hidden" name="stack_name" value="{{.StackName}}">
                                <button type="submit" class="btn btn-xs btn-outline" data-confirm="Visszaállítja a hiányzó fájlokat a másodlagos másolatból? A meglévő fájlok NEM módosulnak és NEM törlődnek. Az alkalmazás a művelet idejére leáll. Legutóbbi másolat: {{.Tier2LastRun}}">Fájlok visszaállítása</button>
                            </form>
                            {{end}}
                            <a href="/stacks/{{.StackName}}/backup" class="btn btn-xs btn-outline">Beállítás</a>
                        </div>
                    {{else}}
                        <span class="layer-auto-ok"><svg class="ico ico-sm"><use href="#i-check"/></svg> 1. mentés auto</span>
                        <span class="layer-unconfigured"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> Nincs 2. (off-drive) másolat</span>
                        {{if .Tier2LastError}}
                        <span class="layer-reason" style="opacity:.85" title="A 2. mentés automatikus — külön beállítás nem kell">{{.Tier2LastError}}</span>
                        {{end}}
                        <div class="layer-actions">
                            <a href="/stacks/{{.StackName}}/backup" class="btn btn-xs btn-outline">Beállítás</a>
                        </div>
                    {{end}}
                </div>
                <!-- Tier 3: Off-box (NAS) backup — real state (see tier3State). -->
                {{if eq .Tier3State "active"}}
                <div class="backup-layer-row">
                    <span class="tier-label">3. mentés</span>
                    <span class="layer-badge {{if eq $.Offbox.LastStatus "ok"}}text-ok{{else if eq $.Offbox.LastStatus "error"}}text-error{{else if eq $.Offbox.LastStatus "running"}}text-muted{{end}}">{{if eq $.Offbox.LastStatus "ok"}}Sikeres{{else if eq $.Offbox.LastStatus "error"}}Hiba{{else if eq $.Offbox.LastStatus "running"}}Fut...{{else}}—{{end}}</span>
                    <span class="tier-location">restic → {{$.Offbox.Host}}</span>
                    {{if $.Offbox.LastRun}}<span class="layer-last">Utolsó: {{timeAgoStr $.Offbox.LastRun}}</span>{{end}}
                    <span class="tier-contents">Helyreállítási egység, titkosítva</span>
                </div>
                {{else if eq .Tier3State "escrow_pending"}}
                <div class="backup-layer-row">
                    <span class="tier-label">3. mentés</span>
                    <span class="layer-badge text-error">Kulcsletétre vár</span>
                    <span class="tier-contents">A távoli mentés a titkosítási kulcs letétbe helyezéséig szünetel</span>
                </div>
                {{else if eq .Tier3State "off"}}
                <div class="backup-layer-row" style="opacity:.5">
                    <span class="tier-label">3. mentés</span>
                    <span class="layer-badge">Kikapcsolva</span>
                    <span class="tier-contents">Ez az alkalmazás nincs kijelölve távoli mentésre</span>
                    <div class="layer-actions">
                        <a href="/backups/remote#offbox-section" class="btn btn-xs btn-outline">Bekapcsolás</a>
                    </div>
                </div>
                {{else}}
                <div class="backup-layer-row" style="opacity:.5">
                    <span class="tier-label">3. mentés</span>
                    <span class="layer-badge" style="background:var(--bg-2);color:var(--text-3)">Nincs beállítva</span>
                    <span class="tier-location">távoli (offsite)</span>
                    <span class="tier-contents">Nincs távoli mentési cél beállítva</span>
                    <div class="layer-actions">
                        <a href="/backups/remote#offbox-section" class="btn btn-xs btn-outline">Beállítás</a>
                    </div>
                </div>
                {{end}}
            </div>
            {{if .Warnings}}
            <div class="layer-warnings">
                {{range .Warnings}}
                <div class="backup-layer-warning">{{.}}</div>
                {{end}}
            </div>
            {{end}}
        </div>
    </div>
    {{end}}

</div>
{{end}}

{{end}}

<script>
{{template "restore_banner_js"}}
function toggleBackupDetail(header) {
    var detail = header.nextElementSibling;
    var icon = header.querySelector('.expand-icon');
    if (detail.style.display === 'none') {
        detail.style.display = 'block';
        icon.textContent = '▼';
    } else {
        detail.style.display = 'none';
        icon.textContent = '▶';
    }
}

function triggerBackupFromPage() {
    const btn = document.getElementById('backup-page-btn');
    btn.disabled = true;
    btn.textContent = 'Mentés indítása...';
    fetch('/api/backup/run', { method: 'POST', headers: csrfHeaders() })
        .then(r => r.json())
        .then(data => {
            if (data.ok) {
                btn.textContent = 'Mentés folyamatban...';
                btn.classList.add('loading');
                startBackupPolling();
            } else {
                btn.textContent = data.error || 'Hiba';
                setTimeout(() => { btn.textContent = 'Mentés most'; btn.disabled = false; }, 3000);
            }
        })
        .catch(() => {
            btn.textContent = 'Hiba';
            setTimeout(() => { btn.textContent = 'Mentés most'; btn.disabled = false; }, 3000);
        });
}

function startBackupPolling() {
    const poll = setInterval(() => {
        fetch('/api/backup/status')
            .then(r => r.json())
            .then(data => {
                if (data.ok && data.data && !data.data.running) {
                    clearInterval(poll);
                    window.location.reload();
                }
            })
            .catch(() => {});
    }, 3000);
}

// Auto-poll if backup is already running on page load
{{if .Backup}}{{if .Backup.Running}}
startBackupPolling();
{{end}}{{end}}
</script>

{{template "layout_end" .}}
{{end}}
