// Einstellungen — Datensicherung (Backup & Restore)
// Export all rf-* data (from IndexedDB via RFDB) as a single JSON file, and import one back.

const { useState: useStateBkp, useEffect: useEffectBkp, useRef: useRefBkp, useMemo: useMemoBkp } = React;

// Keys we treat as "your data". Everything written by useLocal in interactive.jsx
// is prefixed with rf-, so we just enumerate localStorage at export time.
// All values are JSON-encoded (useLocal does JSON.stringify on write) so we
// can safely roundtrip them through JSON.parse → JSON.stringify.
const RF_PREFIX = 'rf-';
const LAST_EXPORT_KEY = 'rf-last-export';
const CLEAN_SLATE_KEY = 'rf-clean-slate-v1'; // wiping this would re-run first-boot purge after import
const BACKUP_VERSION = 1;
const BACKUP_APP     = 'RentFlow Manager';

// ─────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────
function collectBackup() {
  const data = {};
  if (window.RFDB) {
    // Read from IndexedDB in-memory cache (authoritative source)
    window.RFDB.keys().forEach(k => {
      if (k === LAST_EXPORT_KEY) return;
      if (k === CLEAN_SLATE_KEY) return;
      const raw = window.RFDB.getRaw(k);
      if (raw !== null) data[k] = raw;
    });
  } else {
    // Fallback: iterate localStorage
    for (let i = 0; i < localStorage.length; i++) {
      const k = localStorage.key(i);
      if (!k || !k.startsWith(RF_PREFIX)) continue;
      if (k === LAST_EXPORT_KEY) continue;
      if (k === CLEAN_SLATE_KEY) continue;
      data[k] = localStorage.getItem(k);
    }
  }
  return {
    app: BACKUP_APP,
    version: BACKUP_VERSION,
    exportedAt: new Date().toISOString(),
    data,
  };
}

function countItems(parsed) {
  // parsed.data is the { 'rf-rentals-v2': <raw-or-JSON>, ... } payload.
  // Old backups stored already-parsed objects; new backups store the raw
  // stringified form. Tolerate both.
  const rawD = (parsed && parsed.data) || {};
  const d = {};
  Object.entries(rawD).forEach(([k, v]) => {
    if (typeof v === 'string') {
      try { d[k] = JSON.parse(v); } catch { d[k] = v; }
    } else {
      d[k] = v;
    }
  });
  const len = (k) => Array.isArray(d[k]) ? d[k].length : 0;
  const tasksLen = d['rf-tasks'] && Array.isArray(d['rf-tasks'].items) ? d['rf-tasks'].items.length : 0;
  const genDocsCount = (() => {
    const g = d['rf-gendocs'];
    if (!g || typeof g !== 'object') return 0;
    return Object.values(g).reduce((s, v) => s + (Array.isArray(v) ? v.length : 0), 0);
  })();
  return {
    equipment: len('rf-equipment-v2'),
    rentals:   len('rf-rentals-v2'),
    events:    len('rf-events-v2'),
    emails:    len('rf-emails-v1'),
    protocols: len('rf-protocols'),
    tasks:     tasksLen,
    docs:      genDocsCount,
    transactions: len('rf-transactions'),
    hasCompany: !!d['rf-company'],
    installedAt: d['rf-installed-at'] || null,
    keyCount:  Object.keys(rawD).length,
  };
}

function bytesize(obj) {
  try { return new Blob([JSON.stringify(obj)]).size; }
  catch { return 0; }
}

function fmtBytes(n) {
  if (!n) return '—';
  if (n < 1024) return n + ' B';
  if (n < 1024 * 1024) return (n / 1024).toFixed(1).replace('.', ',') + ' KB';
  return (n / (1024 * 1024)).toFixed(2).replace('.', ',') + ' MB';
}

function fmtDateTimeDE(iso) {
  if (!iso) return null;
  try {
    const d = new Date(iso);
    if (isNaN(d.getTime())) return null;
    const pad = (n) => String(n).padStart(2, '0');
    return `${pad(d.getDate())}.${pad(d.getMonth() + 1)}.${d.getFullYear()} · ${pad(d.getHours())}:${pad(d.getMinutes())}`;
  } catch { return null; }
}

function downloadJSON(filename, payload) {
  const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url; a.download = filename;
  document.body.appendChild(a); a.click();
  setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); }, 100);
}

function backupFilename() {
  const d = new Date();
  const pad = (n) => String(n).padStart(2, '0');
  return `rentflow-backup-${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}.json`;
}

// ─────────────────────────────────────────────────────────────
// Mini stat row inside the export summary card
// ─────────────────────────────────────────────────────────────
function StatLine({ label, value, t, last }) {
  return (
    <div style={{
      display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
      padding: '9px 0',
      borderBottom: !last ? `0.5px solid ${t.sep}` : 'none',
    }}>
      <span style={{ fontSize: 13, color: t.textSec }}>{label}</span>
      <span style={{ fontSize: 14, color: t.text, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{value}</span>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Confirm-import sheet contents
// ─────────────────────────────────────────────────────────────
function ImportConfirm({ open, parsed, fileName, t, onCancel, onConfirm }) {
  if (!open) return null;
  const stats = parsed ? countItems(parsed) : null;
  const when = parsed ? fmtDateTimeDE(parsed.exportedAt) : null;

  return (
    <Sheet open={open} onClose={onCancel} maxHeight="78%">
      <div style={{ padding: '4px 20px 8px' }}>
        <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.4 }}>Sicherung importieren?</div>
        <div style={{ fontSize: 13, color: t.textSec, marginTop: 4, lineHeight: 1.45 }}>
          Alle aktuellen Daten werden ersetzt. Diese Aktion kann nicht rückgängig gemacht werden.
        </div>
      </div>

      <div style={{ padding: '0 16px' }}>
        <div style={{
          background: t.card, borderRadius: 14, padding: '12px 14px',
          boxShadow: t.shadowCard,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingBottom: 8, borderBottom: `0.5px solid ${t.sep}` }}>
            <div style={{
              width: 32, height: 32, borderRadius: 8, background: '#34C75922',
              display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
            }}>
              <Icon d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z M14 2v6h6 M9 13l2 2 4-4" color="#34C759" size={16} sw={1.9}/>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 14, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{fileName || 'backup.json'}</div>
              {when && <div style={{ fontSize: 11, color: t.textSec, marginTop: 1 }}>Erstellt am {when}</div>}
            </div>
          </div>
          {stats && (
            <div style={{ paddingTop: 4 }}>
              <StatLine t={t} label="Equipment" value={stats.equipment}/>
              <StatLine t={t} label="Mietverträge" value={stats.rentals}/>
              <StatLine t={t} label="Termine" value={stats.events}/>
              <StatLine t={t} label="Posteingang" value={stats.emails}/>
              <StatLine t={t} label="Protokolle" value={stats.protocols}/>
              <StatLine t={t} label="Aufgaben" value={stats.tasks}/>
              <StatLine t={t} label="Buchungen (Finanzen)" value={stats.transactions}/>
              <StatLine t={t} label="Dokumente" value={stats.docs}/>
              <StatLine t={t} label="Firmenprofil" value={stats.hasCompany ? 'enthalten' : '—'} last/>
            </div>
          )}
        </div>
      </div>

      <div style={{ padding: '16px 16px 24px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <Pressable onClick={onConfirm} scale={0.97}>
          <div style={{
            background: '#FF3B30', color: '#fff', padding: '14px 16px',
            borderRadius: 12, textAlign: 'center', fontSize: 15, fontWeight: 600,
          }}>Jetzt überschreiben & importieren</div>
        </Pressable>
        <Pressable onClick={onCancel} scale={0.97}>
          <div style={{
            background: t.chipStrong, color: t.text, padding: '14px 16px',
            borderRadius: 12, textAlign: 'center', fontSize: 15, fontWeight: 600,
          }}>Abbrechen</div>
        </Pressable>
      </div>
    </Sheet>
  );
}

// ─────────────────────────────────────────────────────────────
// Main view
// ─────────────────────────────────────────────────────────────
function BackupView({ t, onBack, onClose, toast }) {
  // Tick to refresh sizes / stats after operations
  const [tick, setTick] = useStateBkp(0);
  const refresh = () => setTick(x => x + 1);

  const fileRef = useRefBkp(null);
  const [pending, setPending] = useStateBkp(null); // { parsed, fileName }
  const [resetOpen, setResetOpen] = useStateBkp(false);

  const snapshot = useMemoBkp(() => collectBackup(), [tick]);
  const stats    = useMemoBkp(() => countItems(snapshot), [snapshot]);
  const size     = useMemoBkp(() => bytesize(snapshot),   [snapshot]);
  const lastExport = (() => {
    try {
      // Try RFDB first, fall back to localStorage
      if (window.RFDB) {
        const v = window.RFDB.get(LAST_EXPORT_KEY);
        if (v) return v;
      }
      const raw = localStorage.getItem(LAST_EXPORT_KEY);
      return raw ? JSON.parse(raw) : null;
    } catch { return null; }
  })();
  const lastExportFmt = fmtDateTimeDE(lastExport && lastExport.at);

  // ── Export
  const doExport = () => {
    const payload = collectBackup();
    downloadJSON(backupFilename(), payload);
    const exportMeta = { at: payload.exportedAt };
    if (window.RFDB) window.RFDB.set(LAST_EXPORT_KEY, exportMeta);
    else { try { localStorage.setItem(LAST_EXPORT_KEY, JSON.stringify(exportMeta)); } catch {} }
    refresh();
    toast && toast('Sicherung exportiert');
  };

  // ── Import: file picker
  const openPicker = () => { fileRef.current && fileRef.current.click(); };
  const onFile = (e) => {
    const f = e.target.files && e.target.files[0];
    e.target.value = ''; // allow re-pick of the same file
    if (!f) return;
    const reader = new FileReader();
    reader.onload = (ev) => {
      try {
        const parsed = JSON.parse(ev.target.result);
        if (!parsed || typeof parsed !== 'object' || !parsed.data || typeof parsed.data !== 'object') {
          toast && toast('Datei ist kein gültiges Backup');
          return;
        }
        // Must contain at least one rf- key
        const rfKeys = Object.keys(parsed.data).filter(k => k.startsWith(RF_PREFIX));
        if (rfKeys.length === 0) {
          toast && toast('Datei enthält keine RentFlow-Daten');
          return;
        }
        setPending({ parsed, fileName: f.name });
      } catch {
        toast && toast('Datei konnte nicht gelesen werden');
      }
    };
    reader.onerror = () => toast && toast('Datei konnte nicht gelesen werden');
    reader.readAsText(f);
  };

  // ── Restore confirmed
  const applyImport = () => {
    if (!pending) return;
    const { parsed } = pending;
    try {
      if (window.RFDB) {
        // Import via RFDB (writes to IndexedDB + localStorage in sync)
        window.RFDB.importAll(parsed.data);
        // Mark clean-slate done so the first-boot purge doesn't re-wipe seeds.
        window.RFDB.set(CLEAN_SLATE_KEY, '1');
      } else {
        // Fallback: direct localStorage
        const toDel = [];
        for (let i = 0; i < localStorage.length; i++) {
          const k = localStorage.key(i);
          if (k && k.startsWith(RF_PREFIX) && k !== LAST_EXPORT_KEY) toDel.push(k);
        }
        toDel.forEach(k => localStorage.removeItem(k));
        Object.entries(parsed.data).forEach(([k, v]) => {
          if (!k.startsWith(RF_PREFIX)) return;
          const out = typeof v === 'string' ? v : JSON.stringify(v);
          localStorage.setItem(k, out);
        });
        try { localStorage.setItem(CLEAN_SLATE_KEY, '1'); } catch {}
      }
      setPending(null);
      toast && toast('Sicherung wird geladen…');
      // Reload to re-hydrate all React state from the new data.
      setTimeout(() => window.location.reload(), 500);
    } catch (err) {
      console.error(err);
      toast && toast('Import fehlgeschlagen');
    }
  };

  // ── Hard reset: a TRUE factory wipe. Everything under rf-* is removed so no
  // user data survives. Functional document templates (protocols / quick-texts)
  // fall back to their in-script defaults; the company profile falls back to a
  // BLANK profile (DEFAULT_COMPANY no longer carries demo identity) — so no old
  // data can "pop back up" after a reset.
  const doReset = () => {
    setResetOpen(false);
    try {
      if (window.RFDB) {
        // Remove all rf-* keys via RFDB (clears both IndexedDB and localStorage)
        window.RFDB.keys().forEach(k => window.RFDB.remove(k));
        // Re-set the clean-slate flag so the first-boot purge doesn't run again.
        window.RFDB.set(CLEAN_SLATE_KEY, '1');
      } else {
        const toDel = [];
        for (let i = 0; i < localStorage.length; i++) {
          const k = localStorage.key(i);
          if (k && k.startsWith(RF_PREFIX)) toDel.push(k);
        }
        toDel.forEach(k => localStorage.removeItem(k));
        try { localStorage.setItem(CLEAN_SLATE_KEY, '1'); } catch {}
      }
      toast && toast('Auf Werkszustand zurückgesetzt');
      setTimeout(() => window.location.reload(), 400);
    } catch {
      toast && toast('Zurücksetzen fehlgeschlagen');
    }
  };

  return (
    <div>
      <SubHeader title="Datensicherung" onBack={onBack} onClose={onClose} t={t}/>

      {/* Hero: status / last export */}
      <div style={{ padding: '12px 16px 0' }}>
        <div style={{
          background: t.card, borderRadius: 16, padding: 14,
          display: 'flex', alignItems: 'center', gap: 12,
          boxShadow: t.shadowCard,
        }}>
          <div style={{
            width: 48, height: 48, borderRadius: 12, flexShrink: 0,
            background: lastExport ? '#34C75922' : '#FF950022',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <Icon
              d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4 M7 10l5 5 5-5 M12 15V3"
              color={lastExport ? '#34C759' : '#FF9500'} size={24} sw={1.9}/>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 15, fontWeight: 700, color: t.text, letterSpacing: -0.2 }}>
              {lastExportFmt ? 'Letzte Sicherung' : 'Noch keine Sicherung'}
            </div>
            <div style={{ fontSize: 12, color: t.textSec, marginTop: 2, lineHeight: 1.4 }}>
              {lastExportFmt
                ? lastExportFmt
                : 'Erstelle ein Backup um deine Daten zu sichern.'}
            </div>
          </div>
        </div>
      </div>

      {/* Datenbestand */}
      <GroupLabel t={t}>Aktueller Datenbestand</GroupLabel>
      <GroupCard t={t}>
        <div style={{ padding: '4px 14px' }}>
          <StatLine t={t} label="Equipment"    value={stats.equipment}/>
          <StatLine t={t} label="Mietverträge" value={stats.rentals}/>
          <StatLine t={t} label="Termine"      value={stats.events}/>
          <StatLine t={t} label="Posteingang"  value={stats.emails}/>
          <StatLine t={t} label="Protokolle"   value={stats.protocols}/>
          <StatLine t={t} label="Aufgaben"     value={stats.tasks}/>
          <StatLine t={t} label="Buchungen (Finanzen)" value={stats.transactions}/>
          <StatLine t={t} label="Dokumente"    value={stats.docs}/>
          <StatLine t={t} label="Backup-Grösse" value={fmtBytes(size)} last/>
        </div>
      </GroupCard>

      {/* Export */}
      <GroupLabel t={t}>Sicherung erstellen</GroupLabel>
      <div style={{ padding: '0 16px' }}>
        <Pressable onClick={doExport} scale={0.985}>
          <div style={{
            background: t.accent, color: '#fff',
            padding: '14px 16px', borderRadius: 14,
            display: 'flex', alignItems: 'center', gap: 12,
            boxShadow: t.shadowCard,
          }}>
            <Icon d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4 M7 10l5 5 5-5 M12 15V3" color="#fff" size={20} sw={2}/>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 15, fontWeight: 700, letterSpacing: -0.1 }}>Backup exportieren</div>
              <div style={{ fontSize: 12, opacity: 0.85, marginTop: 1 }}>Als .json-Datei herunterladen</div>
            </div>
          </div>
        </Pressable>
      </div>
      <HintLine t={t}>
        Enthält alle Mietverträge, Equipment, Termine, Dokumente, Protokolle und das Firmenprofil.
        Bewahre die Datei an einem sicheren Ort auf — z.B. iCloud Drive.
      </HintLine>

      {/* Import */}
      <GroupLabel t={t}>Sicherung wiederherstellen</GroupLabel>
      <div style={{ padding: '0 16px' }}>
        <Pressable onClick={openPicker} scale={0.985}>
          <div style={{
            background: t.card, color: t.text,
            padding: '14px 16px', borderRadius: 14,
            display: 'flex', alignItems: 'center', gap: 12,
            boxShadow: t.shadowCard,
            border: `0.5px solid ${t.sep}`,
          }}>
            <div style={{
              width: 36, height: 36, borderRadius: 9, background: t.accentSoft,
              display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
            }}>
              <Icon d="M21 9v10a2 2 0 01-2 2H5a2 2 0 01-2-2V9 M17 14l-5-5-5 5 M12 9v12" color={t.accent} size={18} sw={2}/>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 15, fontWeight: 700, letterSpacing: -0.1 }}>Backup importieren</div>
              <div style={{ fontSize: 12, color: t.textSec, marginTop: 1 }}>.json-Datei vom Gerät auswählen</div>
            </div>
            <Icon d={icons.chev} color={t.textTer} size={15} sw={2.2}/>
          </div>
        </Pressable>
        <input ref={fileRef} type="file" accept="application/json,.json" onChange={onFile} style={{ display: 'none' }}/>
      </div>
      <HintLine t={t}>
        Beim Import werden alle aktuellen Daten in der App ersetzt. Du wirst vorher gefragt.
      </HintLine>

      {/* Gefahrenzone */}
      <GroupLabel t={t}>Gefahrenzone</GroupLabel>
      <GroupCard t={t}>
        <ListRow t={t} last
          title="App auf Werkszustand zurücksetzen"
          sub="Löscht ALLE Daten unwiderruflich — Equipment, Mieter, Termine, Buchungen, Aufgaben, E‑Mails, Dokumente, Kategorien, Logistik, Firmenprofil und alle Einstellungen. Die App startet wie frisch installiert."
          right={
            <Pressable onClick={() => setResetOpen(true)} scale={0.95}>
              <div style={{
                padding: '7px 12px', borderRadius: 9,
                background: t.redSoft, color: t.red,
                fontSize: 13, fontWeight: 600,
              }}>Werkszustand</div>
            </Pressable>
          }
        />
      </GroupCard>

      <div style={{ height: 24 }}/>

      {/* Sheets */}
      <ImportConfirm open={!!pending} parsed={pending && pending.parsed}
        fileName={pending && pending.fileName} t={t}
        onCancel={() => setPending(null)} onConfirm={applyImport}/>

      <Confirm open={resetOpen}
        title="App auf Werkszustand zurücksetzen?"
        message="Alle Daten — Equipment, Mieter, Termine, Buchungen, Aufgaben, E-Mails, Dokumente, Firmenprofil und Einstellungen — werden unwiderruflich gelöscht und die App auf den Werkszustand zurückgesetzt. Wenn du die Daten behalten möchtest, exportiere vorher eine Sicherung."
        confirmLabel="Werkszustand"
        onCancel={() => setResetOpen(false)}
        onConfirm={doReset}/>
    </div>
  );
}

Object.assign(window, { BackupView });
