import React, { useState } from "react";
import { STORAGE_KEY, DEFAULT_ABSENZ_TYPES } from "../constants.js";
import { formatIban, isQRIban, applyProjectNumberFormat, applyProtoNumberFormat, generateId, getFeiertageForYear, getAbsenzTypes } from "../utils.js";
import { Header, FormField, Modal, DateInput, useConfirm } from "../components/UI.jsx";

const PERMISSION_GROUPS = [
  { label: "Grundmodule", items: [
    { id: "dashboard", label: "Übersicht" },
    { id: "projects", label: "Projekte" },
    { id: "time", label: "Zeiterfassung" },
    { id: "personen", label: "Kunden & Partner" },
  ]},
  { label: "Buchhaltung", items: [
    { id: "invoices", label: "Rechnungen" },
    { id: "expenses", label: "Spesen" },
    { id: "internal-expenses", label: "Ausgaben" },
    { id: "loehne", label: "Löhne" },
    { id: "studio-budget", label: "Budget" },
  ]},
  { label: "Dokumente", items: [
    { id: "quotes", label: "Offerten" },
    { id: "protokolle", label: "Protokolle" },
    { id: "lieferscheine", label: "Lieferscheine" },
    { id: "letters", label: "Briefe" },
  ]},
  { label: "Administration", items: [
    { id: "mitarbeiter", label: "Mitarbeiter (inkl. Zeiterfassung aller MA)" },
    { id: "settings", label: "Einstellungen / Mein Profil" },
    { id: "dashboard-vorlage", label: "Dashboard-Vorlagen speichern" },
    { id: "pinnwand-schreiben", label: "Pinnwand — Beiträge verfassen" },
  ]},
];

const TABS = [
  { id: "studio",    label: "Studio" },
  { id: "dokumente", label: "Dokumente & Formate" },
  { id: "team",      label: "Team & Rollen" },
  { id: "kalender",  label: "Feiertage & Absenzen" },
  { id: "system",    label: "System" },
  { id: "profil",    label: "Mein Profil" },
];

const SETTINGS_TABS = new Set(["studio", "dokumente", "team", "system"]);

function Section({ title, children }) {
  return (
    <div style={{ marginBottom: 28 }}>
      <div style={{ fontSize: 10, letterSpacing: "0.12em", color: "#aaa", fontWeight: 600, marginBottom: 14, paddingBottom: 8, borderBottom: "1px solid #ece8e2" }}>{title}</div>
      {children}
    </div>
  );
}

function FmtRow({ label, value, onChange, placeholder, preview }) {
  return (
    <div style={{ marginBottom: 12 }}>
      <div style={{ fontSize: 12, color: "#555", marginBottom: 5 }}>{label}</div>
      <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
        <input value={value} onChange={e => onChange(e.target.value)} style={{ maxWidth: 160, fontFamily: "monospace" }} placeholder={placeholder} />
        {preview && <span style={{ fontSize: 12, color: "#2d6a4f", fontWeight: 500 }}>→ {preview}</span>}
      </div>
    </div>
  );
}

function PersonalSettings({ data, update, currentUser, uiZoom, setUiZoom, nav = null }) {
  const emp = (data.employees || []).find(e => e.id === currentUser.employeeId || e.name === currentUser.displayName);
  const userRec = (data.users || []).find(u => u.id === currentUser.id);
  const [empForm, setEmpForm] = useState({
    street: emp?.street || "",
    zip: emp?.zip || "",
    city: emp?.city || "",
    lohnIban: emp?.lohnIban || "",
  });
  const [saved, setSaved] = useState(false);
  const zoomStep = 0.05;

  const saveProfile = () => {
    if (emp) {
      update("employees", (data.employees || []).map(e => e.id === emp.id ? { ...e, ...empForm } : e));
    }
    setSaved(true);
    setTimeout(() => setSaved(false), 2500);
  };

  const uploadAvatar = (e) => {
    const file = e.target.files?.[0]; if (!file) return;
    if (!file.type.startsWith("image/")) { alert("Bitte ein Bild auswählen."); e.target.value = ""; return; }
    const reader = new FileReader();
    reader.onload = (ev) => {
      const img = new Image();
      img.onload = () => {
        const max = 256; // avatar — keep tiny so localStorage stays slim
        const scale = Math.min(1, max / Math.max(img.width, img.height));
        const w = Math.round(img.width * scale);
        const h = Math.round(img.height * scale);
        const canvas = document.createElement("canvas");
        canvas.width = w; canvas.height = h;
        canvas.getContext("2d").drawImage(img, 0, 0, w, h);
        const avatar = canvas.toDataURL("image/jpeg", 0.85);
        update("users", (data.users || []).map(u => u.id === currentUser.id ? { ...u, avatar } : u));
      };
      img.src = ev.target.result;
    };
    reader.readAsDataURL(file);
    e.target.value = "";
  };

  return (
    <div>
      <Header title="Mein Profil" action={
        <button className="btn btn-primary" style={{ background: saved ? "#2d6a4f" : "#2a2a22", transition: "background 0.3s" }} onClick={saveProfile}>
          {saved ? "✓ Gespeichert" : "Speichern"}
        </button>
      } />

      {nav}

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="responsive-grid-2">
        <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
          <div className="card">
            <Section title="PROFIL">
              <div style={{ display: "flex", alignItems: "center", gap: 16, marginBottom: 6 }}>
                <div style={{ width: 64, height: 64, borderRadius: "50%", background: "#f0ede8", border: "2px solid #ece8e2", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 24, color: "#888", overflow: "hidden", flexShrink: 0 }}>
                  {userRec?.avatar
                    ? <img src={userRec.avatar} alt="Profil" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                    : (currentUser.displayName || currentUser.username).charAt(0).toUpperCase()}
                </div>
                <div>
                  <div style={{ fontSize: 14, fontWeight: 500, color: "#1a1a18", marginBottom: 6 }}>{currentUser.displayName || currentUser.username}</div>
                  <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                    <label className="btn btn-ghost" style={{ padding: "5px 12px", fontSize: 11, cursor: "pointer" }}>
                      {userRec?.avatar ? "Ersetzen" : "Foto hochladen"}
                      <input type="file" accept="image/*" style={{ display: "none" }} onChange={uploadAvatar} />
                    </label>
                    {userRec?.avatar && (
                      <button className="btn btn-danger" style={{ padding: "5px 10px", fontSize: 11 }}
                        onClick={() => update("users", (data.users || []).map(u => u.id === currentUser.id ? { ...u, avatar: null } : u))}>
                        <span className="material-icons" style={{ fontSize: 16 }}>close</span>
                      </button>
                    )}
                  </div>
                </div>
              </div>
            </Section>

            <Section title="MEINE ADRESSE">
              <FormField label="Strasse + Nr.">
                <input value={empForm.street} onChange={e => setEmpForm(f => ({ ...f, street: e.target.value }))} placeholder="z.B. Musterstrasse 1" />
              </FormField>
              <div className="form-row">
                <FormField label="PLZ"><input value={empForm.zip} onChange={e => setEmpForm(f => ({ ...f, zip: e.target.value }))} style={{ maxWidth: 120 }} /></FormField>
                <FormField label="Ort"><input value={empForm.city} onChange={e => setEmpForm(f => ({ ...f, city: e.target.value }))} /></FormField>
              </div>
              {!emp && (
                <div style={{ fontSize: 11, color: "#b5621e", marginTop: 6, padding: "8px 12px", background: "#fdf0e8", borderRadius: 8 }}>
                  Kein verknüpfter Mitarbeitereintrag gefunden. Wende dich an den Administrator.
                </div>
              )}
            </Section>
          </div>
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
          <div className="card">
            <Section title="LOHNKONTO">
              <FormField label="IBAN">
                <input value={empForm.lohnIban} onChange={e => setEmpForm(f => ({ ...f, lohnIban: formatIban(e.target.value) }))} placeholder="CH00 0000 0000 0000 0000 0" />
              </FormField>
              <div style={{ fontSize: 11, color: "#aaa", marginTop: 6, lineHeight: 1.6 }}>
                Diese Angabe wird für die Lohnüberweisung verwendet und ist nur für den Administrator sichtbar.
              </div>
              {!emp && (
                <div style={{ fontSize: 11, color: "#b5621e", marginTop: 6, padding: "8px 12px", background: "#fdf0e8", borderRadius: 8 }}>
                  Kein verknüpfter Mitarbeitereintrag gefunden.
                </div>
              )}
            </Section>
          </div>

          <div className="card">
            <Section title="DARSTELLUNG">
              <div style={{ fontSize: 12, color: "#555", marginBottom: 12 }}>Skalierung / Zoom</div>
              <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
                <button onClick={() => setUiZoom(z => Math.max(0.5, Math.round((z - zoomStep) * 100) / 100))} style={{ width: 36, height: 36, border: "1.5px solid #ddd8d0", borderRadius: "50%", background: "none", fontSize: 20, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", fontFamily: "inherit" }}>−</button>
                <div style={{ flex: 1, textAlign: "center" }}>
                  <div style={{ fontSize: 22, fontWeight: 500, fontFamily: "monospace", color: "#1a1a18" }}>{Math.round((uiZoom || 1) * 100)}%</div>
                </div>
                <button onClick={() => setUiZoom(z => Math.min(1.5, Math.round((z + zoomStep) * 100) / 100))} style={{ width: 36, height: 36, border: "1.5px solid #ddd8d0", borderRadius: "50%", background: "none", fontSize: 20, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", fontFamily: "inherit" }}>+</button>
              </div>
              {(uiZoom || 1) !== 1 && (
                <button className="btn btn-ghost" style={{ marginTop: 12, fontSize: 11, width: "100%" }} onClick={() => setUiZoom(1)}>
                  ↺ Auf 100% zurücksetzen
                </button>
              )}
            </Section>
          </div>
        </div>
      </div>
    </div>
  );
}

export default function Settings({ data, update, currentUser, uiZoom, setUiZoom }) {
  const [s, setS] = useState(data.settings);
  const [saved, setSaved] = useState(false);
  const [initModal, setInitModal] = useState(false);
  const [tab, setTab] = useState("studio");
  const [editingRoleId, setEditingRoleId] = useState(null);
  const [roleForm, setRoleForm] = useState(null);
  const [ftForm, setFtForm] = useState({ date: "", label: "", stundenDelta: 0, repeatsYearly: true });
  const [absenzTypeForm, setAbsenzTypeForm] = useState({ label: "", color: "#555" });
  const [kalModal, setKalModal] = useState(null);
  const { askConfirm, ConfirmModalEl } = useConfirm();
  const isDirty = JSON.stringify(s) !== JSON.stringify(data.settings);
  const isAdmin = !currentUser || currentUser.role === "admin";

  const setField = (changes) => { setS(prev => ({ ...prev, ...changes })); setSaved(false); };

  const save = () => {
    update("settings", s);
    setSaved(true);
    setTimeout(() => setSaved(false), 2500);
  };

  const exportData = () => {
    // Strip legacy plaintext passwords; PBKDF2 hashes (passwordHash + passwordSalt) are
    // not reversible and remain in the backup so restored accounts keep working.
    const sanitized = {
      ...data,
      users: (data.users || []).map(u => {
        // eslint-disable-next-line no-unused-vars
        const { password, ...rest } = u;
        return rest;
      }),
    };
    const blob = new Blob([JSON.stringify(sanitized, null, 2)], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `studio-backup-${new Date().toISOString().slice(0, 10)}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const importData = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = async evt => {
      try {
        const imported = JSON.parse(evt.target.result);
        if (await askConfirm("Aktuelle Daten wirklich überschreiben?", "Überschreiben")) {
          localStorage.setItem(STORAGE_KEY, JSON.stringify(imported));
          window.location.reload();
        }
      } catch {
        alert("Datei konnte nicht gelesen werden.");
      }
    };
    reader.readAsText(file);
  };

  // Number format previews
  const invFmt = s.invoiceNumberFormat || "YYYY-NNN";
  const _now = new Date(); const _yyyy = String(_now.getFullYear()); const _yy = _yyyy.slice(2);
  const _invPadLen = (invFmt.match(/N+/) || ["NNN"])[0].length;
  const invFmtPreview = invFmt.replace(/YYYY/g, _yyyy).replace(/YY/g, _yy).replace(/N+/, String(1).padStart(_invPadLen, "0"));
  const protoFmt = s.protokollNumberFormat || "PP-TT-NN";
  const protoAbbr = s.protokollTypeAbbreviations || {};
  const protoFmtPreview = applyProtoNumberFormat(protoFmt, {
    date: new Date().toISOString().slice(0, 10),
    projectNumber: "2026-01",
    seq: 1,
    typKuerzel: Object.values(protoAbbr)[0] || "BS",
  });

  // App-Rollen
  const appRoles = data.appRoles || [];
  const openEditRole = (role) => { setEditingRoleId(role.id); setRoleForm({ ...role, permissions: role.permissions ? [...role.permissions] : null }); };
  const saveRole = () => { update("appRoles", appRoles.map(r => r.id === roleForm.id ? { ...roleForm } : r)); setEditingRoleId(null); };
  const addRole = () => { const nr = { id: generateId(), name: "Neue Rolle", permissions: ["dashboard", "projects", "time"] }; update("appRoles", [...appRoles, nr]); openEditRole(nr); };
  const deleteRole = async (id) => { if (!await askConfirm("Rolle löschen? Benutzer mit dieser Rolle verlieren ihren Zugang.")) return; update("appRoles", appRoles.filter(r => r.id !== id)); };
  const togglePerm = (permId) => { if (!roleForm || roleForm.permissions === null) return; const cur = roleForm.permissions || []; setRoleForm({ ...roleForm, permissions: cur.includes(permId) ? cur.filter(p => p !== permId) : [...cur, permId] }); };

  // Feiertage & Absenztypen
  const feiertage = data.feiertage || [];
  const absenzTypes = getAbsenzTypes(data);
  const defaultAbsenzIds = new Set(DEFAULT_ABSENZ_TYPES.map(t => t.id));

  const saveFt = () => {
    const isNew = !ftForm.id;
    const ft = { ...ftForm, id: ftForm.id || generateId() };
    update("feiertage", isNew ? [...feiertage, ft] : feiertage.map(f => f.id === ft.id ? ft : f));
    setKalModal(null);
  };
  const delFt = (id) => update("feiertage", feiertage.filter(f => f.id !== id));

  const saveAbsenzType = () => {
    const t = { ...absenzTypeForm, id: absenzTypeForm.id || generateId() };
    const custom = data.absenzTypes || [];
    const exists = custom.some(x => x.id === t.id);
    update("absenzTypes", exists ? custom.map(x => x.id === t.id ? t : x) : [...custom, t]);
    setKalModal(null);
  };
  const delAbsenzType = (id) => {
    const inUse = (data.absences || []).some(a => a.type === id);
    if (inUse) { alert("Dieser Absenztyp ist bereits vergeben und kann nicht gelöscht werden."); return; }
    if (defaultAbsenzIds.has(id)) {
      const custom = data.absenzTypes || [];
      const exists = custom.some(x => x.id === id);
      update("absenzTypes", exists ? custom.map(x => x.id === id ? { ...x, deleted: true } : x) : [...custom, { id, deleted: true }]);
    } else {
      update("absenzTypes", (data.absenzTypes || []).filter(t => t.id !== id));
    }
  };

  if (!isAdmin) {
    return <PersonalSettings data={data} update={update} currentUser={currentUser} uiZoom={uiZoom || 1} setUiZoom={setUiZoom || (() => {})} />;
  }

  return (
    <div>
      {ConfirmModalEl}

      {tab !== "profil" && (
        <div className="filter-bar" style={{ marginBottom: 20 }}>
          {TABS.map(t => (
            <button key={t.id} onClick={() => setTab(t.id)} className={`pill${tab === t.id ? " active" : ""}`}>{t.label}</button>
          ))}
        </div>
      )}

      {/* ── Profil-Tab ── */}
      {tab === "profil" && <PersonalSettings data={data} update={update} currentUser={currentUser} uiZoom={uiZoom || 1} setUiZoom={setUiZoom || (() => {})} nav={
        <div className="filter-bar" style={{ marginBottom: 20 }}>
          {TABS.map(t => (
            <button key={t.id} onClick={() => setTab(t.id)} className={`pill${tab === t.id ? " active" : ""}`}>{t.label}</button>
          ))}
        </div>
      } />}

      {/* ── Settings-Tabs (studio / dokumente / team / system / kalender) ── */}
      {tab !== "profil" && <>
        {initModal && (
          <div className="modal-overlay" onClick={() => setInitModal(false)}>
            <div className="modal" style={{ maxWidth: 440 }} onClick={e => e.stopPropagation()}>
              <div style={{ fontFamily: "'Playfair Display',serif", fontSize: 20, marginBottom: 6 }}>Neu initialisieren</div>
              <p style={{ fontSize: 13, color: "#666", lineHeight: 1.7, marginBottom: 16 }}>
                Die App wird auf den Ausgangszustand zurückgesetzt. Alle Projekte, Rechnungen, Mitarbeitende und Einstellungen gehen unwiderruflich verloren.
              </p>
              <div style={{ padding: "10px 14px", background: "#fdf2f2", border: "1px solid #e0b0b0", borderRadius: 8, fontSize: 12, color: "#8a1a1a", marginBottom: 20, lineHeight: 1.6 }}>
                Backup vorher erstellen empfohlen.
              </div>
              <button className="btn btn-primary" style={{ width: "100%", marginBottom: 10 }} onClick={exportData}>↓ Backup erstellen</button>
              <button className="btn btn-danger" style={{ width: "100%", marginBottom: 10 }} onClick={async () => {
                setInitModal(false);
                if (!await askConfirm("Wirklich initialisieren? Alle Daten gehen verloren.", "Initialisieren")) return;
                localStorage.removeItem(STORAGE_KEY);
                window.location.reload();
              }}>Trotzdem initialisieren</button>
              <button className="btn btn-ghost" style={{ width: "100%" }} onClick={() => setInitModal(false)}>Abbrechen</button>
            </div>
          </div>
        )}

        {/* Feiertage / Absenztypen Modals */}
        {kalModal === "ft" && (
          <Modal title={ftForm.id ? "Feiertag bearbeiten" : "Neuer Feiertag"} onClose={() => setKalModal(null)} onSave={saveFt}>
            <div className="form-row">
              <FormField label="Datum"><DateInput value={ftForm.date || ""} onChange={e => setFtForm({ ...ftForm, date: e.target.value })} autoFocus /></FormField>
              <FormField label="Bezeichnung"><input value={ftForm.label || ""} onChange={e => setFtForm({ ...ftForm, label: e.target.value })} placeholder="z.B. Nationalfeiertag" /></FormField>
            </div>
            <div className="form-row">
              <FormField label="Stunden-Delta (0 = ganzer Tag frei)">
                <input type="number" step={0.5} value={ftForm.stundenDelta ?? 0} onChange={e => setFtForm({ ...ftForm, stundenDelta: +e.target.value })} />
                <div style={{ fontSize: 11, color: "#888", marginTop: 4 }}>z.B. −3.5 für Halbtag, −1 für 1h früher</div>
              </FormField>
              <FormField label=" ">
                <label style={{ display: "flex", alignItems: "center", gap: 8, height: 36, cursor: "pointer", textTransform: "none", fontSize: 13 }}>
                  <input type="checkbox" checked={!!ftForm.repeatsYearly} onChange={e => setFtForm({ ...ftForm, repeatsYearly: e.target.checked })} style={{ width: "auto" }} />
                  Jährlich wiederkehrend
                </label>
              </FormField>
            </div>
          </Modal>
        )}

        {kalModal === "absenztype" && (
          <Modal title={absenzTypeForm.id ? "Absenztyp bearbeiten" : "Neuer Absenztyp"} onClose={() => setKalModal(null)} onSave={saveAbsenzType}>
            <div className="form-row">
              <FormField label="Bezeichnung"><input value={absenzTypeForm.label || ""} onChange={e => setAbsenzTypeForm({ ...absenzTypeForm, label: e.target.value })} autoFocus /></FormField>
              <FormField label="Farbe">
                <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                  <input type="color" value={absenzTypeForm.color || "#555"} onChange={e => setAbsenzTypeForm({ ...absenzTypeForm, color: e.target.value })} style={{ width: 44, height: 36, padding: 2, border: "1px solid #e0dbd4", borderRadius: 4 }} />
                  <input value={absenzTypeForm.color || ""} onChange={e => setAbsenzTypeForm({ ...absenzTypeForm, color: e.target.value })} style={{ flex: 1 }} placeholder="#555" />
                </div>
              </FormField>
            </div>
          </Modal>
        )}

        {/* Stable header — Speichern only for settings tabs */}
        <Header title="Einstellungen" action={
          SETTINGS_TABS.has(tab)
            ? <button className="btn btn-primary" style={{ background: saved ? "#2d6a4f" : isDirty ? "#8a6a3a" : "#2a2a22", transition: "background 0.3s" }} onClick={save}>
                {saved ? "✓ Gespeichert" : isDirty ? "Speichern *" : "Gespeichert"}
              </button>
            : null
        } />

        {/* ── Tab: Studio ── */}
        {tab === "studio" && (
          <>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="responsive-grid-2">
            <div className="card">
              <Section title="STUDIO & ERSCHEINUNGSBILD">
                <div style={{ marginBottom: 16 }}>
                  <div style={{ fontSize: 12, color: "#555", marginBottom: 6 }}>Logo (SVG / PNG)</div>
                  <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                    {s.logo && <img src={s.logo} alt="Logo" style={{ maxHeight: 40, maxWidth: 120, border: "1px solid #ece8e2", borderRadius: 4, padding: 4, background: "#fff" }} />}
                    <label className="btn btn-ghost" style={{ padding: "6px 12px", fontSize: 11, cursor: "pointer" }}>
                      {s.logo ? "Ersetzen" : "Hochladen"}
                      <input type="file" accept="image/svg+xml,image/png,image/jpeg" style={{ display: "none" }} onChange={e => {
                        const file = e.target.files?.[0]; if (!file) return;
                        const reader = new FileReader();
                        reader.onload = ev => setField({ logo: ev.target.result });
                        reader.readAsDataURL(file);
                      }} />
                    </label>
                    {s.logo && <button className="btn btn-danger" style={{ padding: "6px 10px", fontSize: 11 }} onClick={() => setField({ logo: null })}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>}
                  </div>
                </div>
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 }}>
                  <span style={{ fontSize: 12, color: "#555" }}>Logohöhe auf PDFs</span>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <input type="number" min={20} max={200} step={5} value={s.logoSize || 60} onChange={e => setField({ logoSize: +e.target.value })} style={{ width: 70 }} />
                    <span style={{ fontSize: 11, color: "#888" }}>px</span>
                    {(s.logoSize || 60) !== 60 && <button className="btn btn-ghost" style={{ fontSize: 11, padding: "4px 10px" }} onClick={() => setField({ logoSize: 60 })}>↺ Standard</button>}
                  </div>
                </div>
                <FormField label="Name / Firma"><input value={s.name} onChange={e => setField({ name: e.target.value })} /></FormField>
              </Section>

              <Section title="ADRESSE">
                <FormField label="Strasse + Nr."><input value={s.street || ""} onChange={e => setField({ street: e.target.value })} placeholder="z.B. Bahnhofstrasse 1" /></FormField>
                <div className="form-row">
                  <FormField label="PLZ"><input value={s.zip || ""} onChange={e => setField({ zip: e.target.value })} style={{ maxWidth: 120 }} /></FormField>
                  <FormField label="Ort"><input value={s.city || ""} onChange={e => setField({ city: e.target.value })} /></FormField>
                  <FormField label="Land"><input value={s.country || "CH"} onChange={e => setField({ country: e.target.value.toUpperCase() })} maxLength={2} style={{ maxWidth: 80 }} /></FormField>
                </div>
                <div className="form-row">
                  <FormField label="E-Mail"><input type="email" value={s.email} onChange={e => setField({ email: e.target.value })} /></FormField>
                  <FormField label="Telefon"><input value={s.phone} onChange={e => setField({ phone: e.target.value })} /></FormField>
                </div>
              </Section>
            </div>

            <div className="card">
              <Section title="FINANZEN">
                <FormField label="IBAN">
                  <input value={s.iban} onChange={e => { const f = formatIban(e.target.value); setField({ iban: f, ibanType: isQRIban(f) ? "qr" : "normal" }); }} placeholder="CH00 0000 0000 0000 0000 0" />
                  <div style={{ fontSize: 11, color: isQRIban(s.iban) ? "#2d6a4f" : "#b5621e", marginTop: 4 }}>
                    {isQRIban(s.iban) ? "✓ QR-IBAN — strukturierte Referenz verfügbar" : "Normale IBAN — ohne strukturierte Referenz"}
                  </div>
                </FormField>
                <FormField label="MWST-Nr."><input value={s.mwst} onChange={e => setField({ mwst: e.target.value })} /></FormField>
                <div className="form-row">
                  <FormField label="MWST-Satz (%)">
                    <input type="number" step="0.1" value={s.mwstRate} onChange={e => setField({ mwstRate: +e.target.value })} />
                  </FormField>
                  <FormField label="Standard-Stundensatz (CHF)">
                    <input type="number" value={s.defaultHourlyRate} onChange={e => setField({ defaultHourlyRate: +e.target.value })} />
                  </FormField>
                </div>
              </Section>
            </div>
          </div>

          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20, marginTop: 20 }} className="responsive-grid-2">
            <div className="card">
              <Section title="SPESENKATEGORIEN">
                <div style={{ fontSize: 11, color: "#aaa", marginBottom: 12 }}>Kategorien für Mitarbeiterspesen.</div>
                {(s.expenseCategories || []).map((cat, i) => (
                  <div key={i} style={{ display: "flex", gap: 6, marginBottom: 6, alignItems: "center" }}>
                    <input value={cat} onChange={e => setField({ expenseCategories: (s.expenseCategories || []).map((c, j) => j === i ? e.target.value : c) })} style={{ flex: 1, fontSize: 12 }} />
                    <button className="btn btn-danger" style={{ padding: "0 7px", height: 30, fontSize: 11 }} onClick={() => setField({ expenseCategories: (s.expenseCategories || []).filter((_, j) => j !== i) })}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>
                  </div>
                ))}
                <button className="btn btn-ghost" style={{ marginTop: 4, fontSize: 11 }} onClick={() => setField({ expenseCategories: [...(s.expenseCategories || []), ""] })}>+ Kategorie</button>
              </Section>
            </div>
            <div className="card">
              <Section title="INTERNE AUSGABEN-KATEGORIEN">
                <div style={{ fontSize: 11, color: "#aaa", marginBottom: 12 }}>Kategorien für interne Büroausgaben.</div>
                {(s.internalExpenseCategories || []).map((cat, i) => (
                  <div key={i} style={{ display: "flex", gap: 6, marginBottom: 6, alignItems: "center" }}>
                    <input value={cat} onChange={e => setField({ internalExpenseCategories: (s.internalExpenseCategories || []).map((c, j) => j === i ? e.target.value : c) })} style={{ flex: 1, fontSize: 12 }} />
                    <button className="btn btn-danger" style={{ padding: "0 7px", height: 30, fontSize: 11 }} onClick={() => setField({ internalExpenseCategories: (s.internalExpenseCategories || []).filter((_, j) => j !== i) })}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>
                  </div>
                ))}
                <button className="btn btn-ghost" style={{ marginTop: 4, fontSize: 11 }} onClick={() => setField({ internalExpenseCategories: [...(s.internalExpenseCategories || []), ""] })}>+ Kategorie</button>
              </Section>
            </div>
          </div>
          </>
        )}

        {/* ── Tab: Dokumente & Formate ── */}
        {tab === "dokumente" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="responsive-grid-2">
            <div className="card">
              <Section title="NUMMERNFORMATE">
                <div style={{ fontSize: 11, color: "#aaa", marginBottom: 14 }}>
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>YYYY</code> = {_yyyy} &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>YY</code> = {_yy} &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>MM</code> = Monat &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>NN</code> = laufende Nr.
                </div>
                <FmtRow label="Projektnummer" value={s.projectNumberFormat || "YYYY/NN"} onChange={v => setField({ projectNumberFormat: v })} placeholder="YYYY/NN" preview={applyProjectNumberFormat(s.projectNumberFormat || "YYYY/NN", 1)} />
                <FmtRow label="Rechnungsnummer" value={invFmt} onChange={v => setField({ invoiceNumberFormat: v })} placeholder="YYYY-NNN" preview={invFmtPreview} />
                <FmtRow label="Protokollnummer" value={protoFmt} onChange={v => setField({ protokollNumberFormat: v })} placeholder="PP-TT-NN" preview={protoFmtPreview} />
                <div style={{ fontSize: 11, color: "#aaa", marginTop: 8, lineHeight: 1.8 }}>
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>PP</code> = Projektnr. ohne Jahreszahl &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>PPP</code> = Projektnr. komplett &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>TT</code> = Sitzungstyp
                </div>
              </Section>

              <Section title="PDF-DATEINAME">
                <div style={{ marginBottom: 8 }}>
                  <input value={s.pdfNameFormat || "{studio}_{typ}_{nummer}"} onChange={e => setField({ pdfNameFormat: e.target.value })} style={{ width: "100%", fontFamily: "monospace" }} placeholder="{studio}_{typ}_{nummer}" />
                </div>
                <div style={{ fontSize: 11, color: "#aaa", lineHeight: 1.8 }}>
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>{"{studio}"}</code> &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>{"{typ}"}</code> &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>{"{nummer}"}</code> &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>{"{kunde}"}</code> &nbsp;
                  <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>{"{datum}"}</code>
                </div>
              </Section>
            </div>

            <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
              <div className="card">
                <Section title="SEITENRÄNDER (MM)">
                  <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px 16px" }}>
                    {[["pageMarginTop", "Oben"], ["pageMarginBottom", "Unten"], ["pageMarginLeft", "Links"], ["pageMarginRight", "Rechts"]].map(([key, label]) => (
                      <div key={key}>
                        <div style={{ fontSize: 11, color: "#888", marginBottom: 4 }}>{label}</div>
                        <input type="number" min={0} max={60} value={s[key] ?? 20} onChange={e => setField({ [key]: +e.target.value })} style={{ width: "100%", fontFamily: "monospace" }} />
                      </div>
                    ))}
                  </div>
                  <div style={{ fontSize: 11, color: "#aaa", marginTop: 10 }}>Gilt für alle Dokumente ausser QR-Rechnung.</div>
                </Section>
              </div>

              <div className="card">
                <Section title="DRUCKOPTIONEN">
                  <label style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", fontSize: 13, color: "#1a1a18", marginBottom: 10 }}>
                    <input type="checkbox" checked={!!s.autoPrint} onChange={e => setField({ autoPrint: e.target.checked })} style={{ width: "auto" }} />
                    Druckdialog automatisch öffnen
                  </label>
                  <label style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", fontSize: 13, color: "#1a1a18" }}>
                    <input type="checkbox" checked={s.qrNewPage !== false} onChange={e => setField({ qrNewPage: e.target.checked })} style={{ width: "auto" }} />
                    QR-Rechnung auf separater Seite
                  </label>
                </Section>
              </div>

              <div className="card">
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14, paddingBottom: 8, borderBottom: "1px solid #ece8e2" }}>
                  <div style={{ fontSize: 10, letterSpacing: "0.12em", color: "#aaa", fontWeight: 600 }}>PROTOKOLL-TYPKÜRZEL</div>
                  <button className="btn btn-ghost" style={{ padding: "3px 10px", fontSize: 11 }} onClick={() => setField({ protokollTypeAbbreviations: { ...protoAbbr, "Neuer Typ": "NT" } })}>+ Typ</button>
                </div>
                <div style={{ fontSize: 11, color: "#aaa", marginBottom: 12 }}>
                  Kürzel für Platzhalter <code style={{ background: "#f0ede8", padding: "1px 4px", borderRadius: 2 }}>TT</code> in der Protokollnummer.
                </div>
                <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                  {Object.entries(protoAbbr).map(([typName, kuerzel]) => (
                    <div key={typName} style={{ display: "flex", gap: 6, alignItems: "center" }}>
                      <input defaultValue={typName} onBlur={e => {
                        const newName = e.target.value.trim();
                        if (!newName || newName === typName) { e.target.value = typName; return; }
                        const newAbbr = Object.fromEntries(Object.entries(protoAbbr).map(([k, v]) => [k === typName ? newName : k, v]));
                        setField({ protokollTypeAbbreviations: newAbbr });
                      }} placeholder="Sitzungstyp" style={{ flex: 1, fontSize: 12 }} />
                      <input value={kuerzel} onChange={e => setField({ protokollTypeAbbreviations: { ...protoAbbr, [typName]: e.target.value.toUpperCase().slice(0, 4) } })}
                        placeholder="BS" style={{ width: 52, textAlign: "center", fontWeight: 600, fontSize: 12, fontFamily: "monospace" }} maxLength={4} />
                      <button className="btn btn-danger" style={{ padding: "0 7px", height: 30, fontSize: 11 }} onClick={() => setField({ protokollTypeAbbreviations: Object.fromEntries(Object.entries(protoAbbr).filter(([k]) => k !== typName)) })}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>
        )}

        {/* ── Tab: Team & Rollen ── */}
        {tab === "team" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="responsive-grid-2">
            <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
              <div className="card">
                <Section title="MITARBEITER-STANDARDS">
                  <div style={{ fontSize: 11, color: "#aaa", marginBottom: 14 }}>Vorausgefüllt bei neuen Mitarbeitern.</div>
                  <FormField label="Wochenstunden (100%)">
                    <input type="number" min={1} max={50} step={0.5} value={s.defaultWochenstunden || 35} onChange={e => setField({ defaultWochenstunden: +e.target.value })} />
                  </FormField>
                  <FormField label="Ferienwochen / Jahr">
                    <input type="number" min={4} max={10} step={0.5} value={s.defaultFerienWochen || 5} onChange={e => setField({ defaultFerienWochen: +e.target.value })} />
                    <div style={{ fontSize: 11, color: "#aaa", marginTop: 3 }}>Minimum gesetzlich: 4 Wochen</div>
                  </FormField>
                  <FormField label="PK / BVG AG-Anteil %">
                    <input type="number" min={0} step={0.1} value={s.defaultPkAGSatz ?? 8.0} onChange={e => setField({ defaultPkAGSatz: +e.target.value })} />
                  </FormField>
                </Section>
              </div>

              <div className="card">
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14, paddingBottom: 8, borderBottom: "1px solid #ece8e2" }}>
                  <div style={{ fontSize: 10, letterSpacing: "0.12em", color: "#aaa", fontWeight: 600 }}>ROLLEN FÜR OFFERTEN</div>
                  <button className="btn btn-ghost" style={{ padding: "3px 10px", fontSize: 11 }} onClick={() => setField({ roles: [...(s.roles || []), { id: "", label: "", rate: s.defaultHourlyRate || 120 }] })}>+ Rolle</button>
                </div>
                <div style={{ fontSize: 11, color: "#aaa", marginBottom: 12 }}>Kürzel, Bezeichnung und Stundensatz für Aufwandschätzungen in Offerten.</div>
                {(s.roles || []).map((r, idx) => (
                  <div key={idx} style={{ display: "flex", gap: 6, marginBottom: 8, alignItems: "center" }}>
                    <input value={r.id} onChange={e => setField({ roles: s.roles.map((x, i) => i === idx ? { ...x, id: e.target.value.toUpperCase().slice(0, 3) } : x) })} placeholder="PL" style={{ width: 46, textAlign: "center", fontSize: 11 }} />
                    <input value={r.label} onChange={e => setField({ roles: s.roles.map((x, i) => i === idx ? { ...x, label: e.target.value } : x) })} placeholder="Bezeichnung" style={{ flex: 1, fontSize: 12 }} />
                    <input type="number" value={r.rate} onChange={e => setField({ roles: s.roles.map((x, i) => i === idx ? { ...x, rate: +e.target.value } : x) })} style={{ width: 72, textAlign: "right", fontSize: 12 }} />
                    <span style={{ fontSize: 11, color: "#888" }}>CHF/h</span>
                    <button className="btn btn-danger" style={{ padding: "0 7px", height: 30, fontSize: 11 }} onClick={() => setField({ roles: s.roles.filter((_, i) => i !== idx) })}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>
                  </div>
                ))}
              </div>
            </div>

            <div className="card">
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8, paddingBottom: 8, borderBottom: "1px solid #ece8e2" }}>
                <div style={{ fontSize: 10, letterSpacing: "0.12em", color: "#aaa", fontWeight: 600 }}>APP-ROLLEN & BERECHTIGUNGEN</div>
                <button className="btn btn-ghost" style={{ padding: "3px 10px", fontSize: 11 }} onClick={addRole}>+ Rolle</button>
              </div>
              <div style={{ fontSize: 11, color: "#aaa", marginBottom: 16 }}>
                Rollen bestimmen, welche Bereiche Mitarbeitende sehen können.
              </div>

              {appRoles.map(role => (
                <div key={role.id} style={{ marginBottom: 10, border: "1.5px solid #ece8e2", borderRadius: 8, overflow: "hidden" }}>
                  <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 14px", background: "#faf8f5" }}>
                    <div>
                      <div style={{ fontSize: 13, fontWeight: 500 }}>{role.name}</div>
                      <div style={{ fontSize: 11, color: "#aaa", marginTop: 2 }}>
                        {role.permissions === null ? "Voller Zugriff" : `${(role.permissions || []).length} Bereiche`}
                        {" · "}{(data.users || []).filter(u => u.appRoleId === role.id).length} Benutzer
                      </div>
                    </div>
                    <div style={{ display: "flex", gap: 6 }}>
                      {editingRoleId === role.id
                        ? <><button className="btn btn-primary" style={{ padding: "4px 12px", fontSize: 11 }} onClick={saveRole}>Speichern</button>
                           <button className="btn btn-ghost" style={{ padding: "4px 10px", fontSize: 11 }} onClick={() => setEditingRoleId(null)}>Abbrechen</button></>
                        : <button className="btn btn-ghost" style={{ padding: "4px 10px", fontSize: 11 }} onClick={() => openEditRole(role)}><span className="material-icons" style={{ fontSize: 16 }}>edit</span></button>
                      }
                      {role.id !== "r-admin" && <button className="btn btn-danger" style={{ padding: "4px 8px", fontSize: 11 }} onClick={() => deleteRole(role.id)}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>}
                    </div>
                  </div>

                  {editingRoleId === role.id && roleForm && (
                    <div style={{ padding: "14px 14px 10px", borderTop: "1px solid #ece8e2" }}>
                      <div style={{ marginBottom: 12 }}>
                        <label style={{ fontSize: 11, color: "#888", display: "block", marginBottom: 5 }}>Rollenname</label>
                        <input value={roleForm.name} onChange={e => setRoleForm({ ...roleForm, name: e.target.value })} style={{ fontSize: 13, width: "100%", maxWidth: 300 }} />
                      </div>
                      <div style={{ marginBottom: 14 }}>
                        <label style={{ display: "flex", alignItems: "center", gap: 8, cursor: "pointer", fontSize: 12, marginBottom: 10 }}>
                          <input type="checkbox" checked={roleForm.permissions === null}
                            onChange={e => setRoleForm({ ...roleForm, permissions: e.target.checked ? null : ["dashboard"] })}
                            style={{ width: "auto" }} />
                          Voller Zugriff (Administrator)
                        </label>
                        {roleForm.permissions !== null && (
                          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))", gap: "10px 20px" }}>
                            {PERMISSION_GROUPS.map(group => (
                              <div key={group.label}>
                                <div style={{ fontSize: 10, letterSpacing: "0.1em", color: "#aaa", marginBottom: 6, fontWeight: 600 }}>{group.label.toUpperCase()}</div>
                                {group.items.map(perm => (
                                  <label key={perm.id} style={{ display: "flex", alignItems: "center", gap: 7, cursor: "pointer", fontSize: 12, marginBottom: 5 }}>
                                    <input type="checkbox" checked={(roleForm.permissions || []).includes(perm.id)} onChange={() => togglePerm(perm.id)} style={{ width: "auto" }} />
                                    {perm.label}
                                  </label>
                                ))}
                              </div>
                            ))}
                          </div>
                        )}
                      </div>
                      <div style={{ paddingTop: 10, borderTop: "1px solid #ece8e2" }}>
                        <label style={{ fontSize: 11, color: "#888", display: "block", marginBottom: 6 }}>Dashboard-Vorlage</label>
                        <select value={roleForm.dashboardTemplateId || ""} onChange={e => setRoleForm({ ...roleForm, dashboardTemplateId: e.target.value || null })} style={{ width: "100%", maxWidth: 300 }}>
                          <option value="">— keine —</option>
                          {(data.dashboardTemplates || []).filter(t => t.isPublic).map(t => <option key={t.id} value={t.id}>{t.name}</option>)}
                        </select>
                      </div>
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>
        )}

        {/* ── Tab: Feiertage & Absenzen ── */}
        {tab === "kalender" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="responsive-grid-2">
            <div className="card">
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14, paddingBottom: 8, borderBottom: "1px solid #ece8e2" }}>
                <div style={{ fontSize: 10, letterSpacing: "0.12em", color: "#aaa", fontWeight: 600 }}>FEIERTAGE</div>
                <button className="btn btn-ghost" style={{ padding: "3px 10px", fontSize: 11 }} onClick={() => { setFtForm({ date: "", label: "", stundenDelta: 0, repeatsYearly: true }); setKalModal("ft"); }}>+ Feiertag</button>
              </div>
              <div style={{ fontSize: 11, color: "#aaa", marginBottom: 14, lineHeight: 1.6 }}>
                Gelten für alle Mitarbeiter. Jährlich wiederkehrende werden automatisch übertragen. Mit «Stunden-Delta» lassen sich Halbfeiertage definieren (z.B. −3.5h für den 24.12.).
              </div>
              <div className="card" style={{ padding: 0, marginBottom: feiertage.length === 0 ? 12 : 0 }}>
                <table>
                  <thead><tr><th>Datum</th><th>Bezeichnung</th><th style={{ textAlign: "right" }}>Delta</th><th></th></tr></thead>
                  <tbody>
                    {feiertage.length === 0 && <tr><td colSpan={4} style={{ textAlign: "center", color: "#aaa", padding: 24 }}>Noch keine Feiertage erfasst</td></tr>}
                    {[...feiertage].sort((a, b) => (a.date || "").slice(5).localeCompare((b.date || "").slice(5))).map(f => (
                      <tr key={f.id}>
                        <td style={{ fontSize: 12 }}>{f.repeatsYearly ? f.date.slice(5).replace("-", ".") + " ↻" : f.date ? new Date(f.date).toLocaleDateString("de-CH") : "—"}</td>
                        <td style={{ fontWeight: 500, fontSize: 12 }}>{f.label}</td>
                        <td style={{ textAlign: "right", fontSize: 12, color: f.stundenDelta < 0 ? "#b5621e" : "#aaa" }}>{f.stundenDelta === 0 || f.stundenDelta === null ? "ganztag" : `${f.stundenDelta}h`}</td>
                        <td style={{ textAlign: "right", whiteSpace: "nowrap" }}>
                          <button className="btn btn-ghost" style={{ padding: "3px 8px", fontSize: 11, marginRight: 4 }} onClick={() => { setFtForm({ ...f }); setKalModal("ft"); }}><span className="material-icons" style={{ fontSize: 16 }}>edit</span></button>
                          <button className="btn btn-danger" style={{ padding: "3px 8px", fontSize: 11 }} onClick={() => delFt(f.id)}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
              {feiertage.length === 0 && (
                <button className="btn btn-ghost" style={{ fontSize: 11, width: "100%" }} onClick={() => {
                  const easterSunday = (year) => {
                    const a = year%19, b = Math.floor(year/100), c = year%100;
                    const d = Math.floor(b/4), e = b%4, f = Math.floor((b+8)/25);
                    const g = Math.floor((b-f+1)/3), h = (19*a+b-d-g+15)%30;
                    const i = Math.floor(c/4), k = c%4;
                    const l = (32+2*e+2*i-h-k)%7;
                    const m = Math.floor((a+11*h+22*l)/451);
                    const month = Math.floor((h+l-7*m+114)/31);
                    const day = ((h+l-7*m+114)%31)+1;
                    return new Date(year, month-1, day);
                  };
                  const addDays = (date, days) => { const d = new Date(date); d.setDate(d.getDate()+days); return d; };
                  const fmt = (date) => `${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`;
                  const yr = new Date().getFullYear();
                  const fixe = [
                    { label: "Neujahr", date: "2000-01-01", stundenDelta: 0, repeatsYearly: true },
                    { label: "Berchtoldstag", date: "2000-01-02", stundenDelta: 0, repeatsYearly: true },
                    { label: "Tag der Arbeit", date: "2000-05-01", stundenDelta: 0, repeatsYearly: true },
                    { label: "Nationalfeiertag", date: "2000-08-01", stundenDelta: 0, repeatsYearly: true },
                    { label: "Weihnachten", date: "2000-12-25", stundenDelta: 0, repeatsYearly: true },
                    { label: "Stephanstag", date: "2000-12-26", stundenDelta: 0, repeatsYearly: true },
                    { label: "Heiligabend (Halbtag)", date: "2000-12-24", stundenDelta: -3.5, repeatsYearly: true },
                    { label: "Silvester (Halbtag)", date: "2000-12-31", stundenDelta: -3.5, repeatsYearly: true },
                  ].map(f => ({ ...f, id: generateId() }));
                  const beweglich = [];
                  for (let y = yr; y <= yr+3; y++) {
                    const ostern = easterSunday(y);
                    [
                      { label: "Karfreitag", offset: -2 },
                      { label: "Ostermontag", offset: 1 },
                      { label: "Auffahrt", offset: 39 },
                      { label: "Auffahrt Vortag (Halbtag)", offset: 38, stundenDelta: -3.5 },
                      { label: "Pfingstmontag", offset: 50 },
                    ].forEach(({ label, offset, stundenDelta = 0 }) => {
                      beweglich.push({ id: generateId(), label, date: fmt(addDays(ostern, offset)), stundenDelta, repeatsYearly: false });
                    });
                  }
                  update("feiertage", [...feiertage, ...fixe, ...beweglich]);
                }}>↓ CH-Vorlagen laden (inkl. Ostern, Auffahrt, Pfingsten…)</button>
              )}
            </div>

            <div className="card">
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14, paddingBottom: 8, borderBottom: "1px solid #ece8e2" }}>
                <div style={{ fontSize: 10, letterSpacing: "0.12em", color: "#aaa", fontWeight: 600 }}>ABSENZTYPEN</div>
                <button className="btn btn-ghost" style={{ padding: "3px 10px", fontSize: 11 }} onClick={() => { setAbsenzTypeForm({ label: "", color: "#555" }); setKalModal("absenztype"); }}>+ Typ</button>
              </div>
              <table>
                <thead><tr><th>Bezeichnung</th><th>Farbe</th><th>Typ</th><th></th></tr></thead>
                <tbody>
                  {absenzTypes.map(t => {
                    const inUse = (data.absences || []).some(a => a.type === t.id);
                    const isDefault = defaultAbsenzIds.has(t.id);
                    const isOverridden = isDefault && (data.absenzTypes || []).some(x => x.id === t.id);
                    return (
                      <tr key={t.id}>
                        <td><span className="tag" style={{ background: t.color, fontSize: 10 }}>{t.label}</span></td>
                        <td style={{ color: "#888", fontSize: 12 }}>{t.color}</td>
                        <td style={{ fontSize: 11, color: isDefault ? (isOverridden ? "#b07848" : "#aaa") : "#2d6a4f" }}>
                          {isDefault ? (isOverridden ? "Angepasst" : "Standard") : "Eigener"}
                        </td>
                        <td style={{ textAlign: "right", whiteSpace: "nowrap" }}>
                          <button className="btn btn-ghost" style={{ padding: "3px 8px", fontSize: 11, marginRight: 4 }} onClick={() => { setAbsenzTypeForm(t); setKalModal("absenztype"); }}><span className="material-icons" style={{ fontSize: 16 }}>edit</span></button>
                          <button className="btn btn-danger" style={{ padding: "3px 8px", fontSize: 11, opacity: inUse ? 0.35 : 1 }} onClick={() => delAbsenzType(t.id)} title={inUse ? "In Verwendung" : "Löschen"}><span className="material-icons" style={{ fontSize: 16 }}>close</span></button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>
        )}

        {/* ── Tab: System ── */}
        {tab === "system" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="responsive-grid-2">
            <div className="card">
              <Section title="DATEN & BACKUP">
                <p style={{ fontSize: 13, color: "#666", lineHeight: 1.7, marginBottom: 16 }}>
                  Alle Daten liegen ausschliesslich im Browser (localStorage). Regelmässige Backups sind empfohlen.
                </p>
                <button className="btn btn-primary" style={{ width: "100%", marginBottom: 10 }} onClick={exportData}>↓ Backup als JSON herunterladen</button>
                <label className="btn btn-ghost" style={{ width: "100%", textAlign: "center", display: "block", marginBottom: 10 }}>
                  ↑ Backup importieren
                  <input type="file" accept=".json" onChange={importData} style={{ display: "none" }} />
                </label>
                <button className="btn btn-danger" style={{ width: "100%" }} onClick={() => setInitModal(true)}>
                  Neu initialisieren…
                </button>
              </Section>

              <Section title="DATENBANKÜBERSICHT">
                {[
                  { label: "Personen", value: (data.persons || []).length },
                  { label: "Projekte", value: data.projects.length },
                  { label: "Zeiteinträge", value: data.timeEntries.length },
                  { label: "Rechnungen", value: data.invoices.length },
                  { label: "Offerten", value: (data.quotes || []).length },
                  { label: "Spesen", value: (data.expenses || []).length },
                  { label: "Interne Ausgaben", value: (data.internalExpenses || []).length },
                ].map(r => (
                  <div key={r.label} style={{ display: "flex", justifyContent: "space-between", padding: "4px 0", fontSize: 12, borderBottom: "1px solid #f0ede8" }}>
                    <span style={{ color: "#888" }}>{r.label}</span>
                    <strong style={{ color: "#555" }}>{r.value}</strong>
                  </div>
                ))}
              </Section>
            </div>

            <div className="card">
              <Section title="ZEITERFASSUNG">
                <label style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", fontSize: 13, color: "#1a1a18" }}>
                  <input type="checkbox" checked={s.blockMaiTag !== false} onChange={e => setField({ blockMaiTag: e.target.checked })} style={{ width: "auto" }} />
                  Tag der Arbeit (1. Mai) in Wochenansicht sperren
                </label>
              </Section>
            </div>
          </div>
        )}
      </>}
    </div>
  );
}
