/* /admin — dedicated admin app. Wrapped in <AuthGate requireRole="admin">
   by app.jsx, so this component can assume the current user is admin. */

function AdminApp() {
  const fb = window.fb;
  const auth = window.useAuth();
  const [tenants, setTenants] = React.useState([]);
  const [users, setUsers] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [showCreate, setShowCreate] = React.useState(false);
  const [selected, setSelected] = React.useState(null); // tenantId

  // Subscribe to /tenants and /users (admin can read all)
  React.useEffect(() => {
    const u1 = fb.onSnapshot(fb.collection(fb.db, "tenants"), (snap) => {
      const out = []; snap.forEach(d => out.push({ id: d.id, ...d.data() }));
      setTenants(out.sort((a,b) => (a.name||'').localeCompare(b.name||'')));
      setLoading(false);
    });
    const u2 = fb.onSnapshot(fb.collection(fb.db, "users"), (snap) => {
      const out = []; snap.forEach(d => out.push({ id: d.id, ...d.data() }));
      setUsers(out);
    });
    return () => { u1(); u2(); };
  }, []);

  const usersByTenant = React.useMemo(() => {
    const m = {};
    users.forEach(u => {
      if (!u.restaurantId) return;
      (m[u.restaurantId] = m[u.restaurantId] || []).push(u);
    });
    return m;
  }, [users]);

  const totalActive = tenants.filter(t => t.active !== false).length;

  const toggleActive = async (t) => {
    await fb.updateDoc(fb.doc(fb.db, "tenants", t.id), { active: !(t.active === false) ? false : true });
  };

  // Hard-delete a tenant: removes all subcollection docs, the tenant
  // doc itself, the /publicTenants slug entry, and all /users docs that
  // pointed at the tenant. Firebase Auth accounts can't be deleted from
  // a client SDK — they're orphaned (admin can manually remove from the
  // Auth console if needed).
  const deleteTenant = async (t) => {
    const subcollections = ["tables","reservations","waitlist","rooms","walls","activity"];
    // 1. Wipe each subcollection in batches
    for (const sub of subcollections) {
      const snap = await fb.getDocs(fb.collection(fb.db, "tenants", t.id, sub));
      if (snap.empty) continue;
      // Firestore batches max 500 ops
      let batch = fb.writeBatch(fb.db);
      let n = 0;
      for (const d of snap.docs) {
        batch.delete(d.ref); n++;
        if (n === 450) { await batch.commit(); batch = fb.writeBatch(fb.db); n = 0; }
      }
      if (n > 0) await batch.commit();
    }
    // 2. Delete the linked /users docs (they only carry restaurantId pointers)
    const linkedUsers = users.filter(u => u.restaurantId === t.id);
    if (linkedUsers.length) {
      const batch = fb.writeBatch(fb.db);
      linkedUsers.forEach(u => batch.delete(fb.doc(fb.db, "users", u.id)));
      await batch.commit();
    }
    // 3. Delete the public slug mirror
    if (t.slug) {
      try { await fb.deleteDoc(fb.doc(fb.db, "publicTenants", t.slug)); } catch (e) {}
    }
    // 4. Finally delete the tenant doc itself
    await fb.deleteDoc(fb.doc(fb.db, "tenants", t.id));
    setSelected(null);
  };

  const onSelected = selected ? tenants.find(t => t.id === selected) : null;

  return (
    <div className="admin-shell">
      <header className="admin-top">
        <div className="brandmark">SEATIQ<span className="dot">.</span></div>
        <div className="admin-eyebrow">ADMIN</div>
        <div style={{flex: 1}}/>
        <div style={{fontSize: 12, color: 'var(--muted)'}}>{auth.userDoc?.email}</div>
        <button className="btn btn-soft" onClick={auth.signOut}><Icon name="logout" size={14}/> Log ud</button>
      </header>

      <div className="page-hero">
        <div className="page-hero-eyebrow">{tenants.length} restauranter · {totalActive} aktive · {users.length} brugere</div>
        <h1 className="page-hero-title">RESTAURANTER</h1>
        <p className="page-hero-sub">Opret nye restauranter, nulstil adgangskoder, og overvåg aktivitet på tværs af systemet.</p>
        <div style={{display: 'flex', gap: 8, marginTop: 16}}>
          <button className="btn btn-accent" onClick={() => setShowCreate(true)}><Icon name="plus" size={14}/> Ny restaurant</button>
        </div>
      </div>

      <div className={`admin-grid ${onSelected ? 'with-detail' : ''}`}>
        <div style={{background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 12, overflow: 'hidden'}}>
          <table className="list-table">
            <thead>
              <tr>
                <th>Restaurant</th>
                <th>Brugere</th>
                <th>Status</th>
                <th>Sidst aktiv</th>
                <th>Oprettet</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {loading && (
                <tr><td colSpan={6} style={{padding: 40, textAlign: 'center', color: 'var(--muted)'}}>Indlæser…</td></tr>
              )}
              {!loading && tenants.length === 0 && (
                <tr><td colSpan={6} style={{padding: 40, textAlign: 'center', color: 'var(--muted)'}}>
                  Ingen restauranter endnu. Klik „Ny restaurant“ for at oprette den første.
                </td></tr>
              )}
              {tenants.map(t => {
                const active = t.active !== false;
                const us = usersByTenant[t.id] || [];
                return (
                  <tr key={t.id}
                    className={selected === t.id ? 'selected' : ''}
                    style={{cursor: 'pointer'}}
                    onClick={() => setSelected(t.id)}>
                    <td>
                      <div style={{fontWeight: 700, fontSize: 14}}>{t.name || t.id}</div>
                      <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 2}}>{t.id}</div>
                    </td>
                    <td>
                      <strong>{us.length}</strong>
                      <span style={{fontSize: 11, color: 'var(--muted)', marginLeft: 6}}>
                        {us[0]?.email}{us.length > 1 ? ` +${us.length-1}` : ''}
                      </span>
                    </td>
                    <td>
                      <span className={`status-chip ${active ? 'confirmed' : 'finished'}`}>
                        {active ? 'aktiv' : 'pause'}
                      </span>
                    </td>
                    <td style={{color: 'var(--muted)', fontSize: 12}}>
                      {fmtRelative(t.lastActivityAt)}
                    </td>
                    <td style={{color: 'var(--muted)', fontSize: 12}}>
                      {fmtRelative(t.createdAt)}
                    </td>
                    <td onClick={e => e.stopPropagation()}>
                      <button className="btn btn-soft" style={{fontSize: 11}} onClick={() => toggleActive(t)}>
                        {active ? 'Sæt på pause' : 'Genaktiver'}
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {onSelected && (
          <TenantDetail
            tenant={onSelected}
            users={usersByTenant[onSelected.id] || []}
            onClose={() => setSelected(null)}
            onToggleActive={() => toggleActive(onSelected)}
            onDelete={() => deleteTenant(onSelected)}
          />
        )}
      </div>

      {showCreate && (
        <CreateRestaurantModal onClose={() => setShowCreate(false)}/>
      )}
    </div>
  );
}

// Mirror a tenant's public booking config to /publicTenants/{slug}.
// Anonymous booking widget reads this without auth. Old slugs (if changed)
// are deleted so the URL doesn't keep resolving.
async function syncPublicTenant(tenantId, patch, oldSlug) {
  const fb = window.fb;
  if (oldSlug && (!patch.slug || oldSlug !== patch.slug)) {
    try { await fb.deleteDoc(fb.doc(fb.db, "publicTenants", oldSlug)); } catch (e) {}
  }
  if (patch.slug) {
    await fb.setDoc(fb.doc(fb.db, "publicTenants", patch.slug), {
      tenantId,
      name: patch.name,
      enabled: !!patch.publicBookingEnabled,
      defaultDurationMin: patch.defaultDurationMin || 105,
      openingHours: patch.openingHours || null,
      lastBookingOffsetMin: patch.lastBookingOffsetMin ?? 60,
      services: patch.services || null,
      policy: patch.policy || null,
    }, { merge: false });
  }
}

// Map a custom hostname (e.g. booking.cafestrand.dk) to a tenant.
// The booking widget reads /domainMappings/{hostname} on load to detect
// a custom-domain tenant before falling back to the /slug route.
async function syncDomainMapping(tenantId, newHost, oldHost) {
  const fb = window.fb;
  const normalize = (h) => String(h||'').toLowerCase().trim().replace(/^https?:\/\//,'').replace(/\/.*$/,'');
  const newH = normalize(newHost);
  const oldH = normalize(oldHost);
  if (oldH && oldH !== newH) {
    try { await fb.deleteDoc(fb.doc(fb.db, "domainMappings", oldH)); } catch (e) {}
  }
  if (newH) {
    await fb.setDoc(fb.doc(fb.db, "domainMappings", newH), {
      tenantId,
      createdAt: fb.serverTimestamp(),
    });
  }
}

function TenantDetail({ tenant, users, onClose, onToggleActive, onDelete }) {
  const fb = window.fb;
  const active = tenant.active !== false;
  const [activity, setActivity] = React.useState([]);
  const [busy, setBusy] = React.useState(null);
  const [editingSlug, setEditingSlug] = React.useState(false);
  const [slugDraft, setSlugDraft] = React.useState(tenant.slug || '');
  const [confirmDelete, setConfirmDelete] = React.useState(false);
  const [deleteText, setDeleteText] = React.useState('');
  const [deleting, setDeleting] = React.useState(false);
  const [editingDomain, setEditingDomain] = React.useState(false);
  const [domainDraft, setDomainDraft] = React.useState(tenant.customDomain || '');

  React.useEffect(() => {
    setSlugDraft(tenant.slug || '');
    setEditingSlug(false);
    setConfirmDelete(false);
    setDeleteText('');
    setEditingDomain(false);
    setDomainDraft(tenant.customDomain || '');
  }, [tenant.id, tenant.slug, tenant.customDomain]);

  const saveDomain = async () => {
    const raw = String(domainDraft || '').toLowerCase().trim()
      .replace(/^https?:\/\//,'').replace(/\/.*$/,'').replace(/^www\./,'');
    if (raw && !/^[a-z0-9.-]+\.[a-z]{2,}$/.test(raw)) {
      alert('Ikke et gyldigt domæne. Eksempel: booking.cafestrand.dk');
      return;
    }
    try {
      // Check collision
      if (raw && raw !== tenant.customDomain) {
        const existing = await fb.getDoc(fb.doc(fb.db, "domainMappings", raw));
        if (existing.exists() && existing.data().tenantId !== tenant.id) {
          alert(`Domænet "${raw}" er allerede koblet til en anden restaurant.`);
          return;
        }
      }
      await fb.setDoc(fb.doc(fb.db, "tenants", tenant.id), {
        customDomain: raw || null,
      }, { merge: true });
      await syncDomainMapping(tenant.id, raw, tenant.customDomain);
      setEditingDomain(false);
    } catch (e) {
      alert("Kunne ikke gemme: " + (e.message || e));
    }
  };

  const removeDomain = async () => {
    if (!confirm(`Fjern det brugerdefinerede domæne "${tenant.customDomain}"?\n\nGæster vil ikke længere kunne booke via dette domæne. Tilbage til ${tenant.slug ? 'booking.ooniq.app/'+tenant.slug : 'standard URL'}.`)) return;
    await fb.setDoc(fb.doc(fb.db, "tenants", tenant.id), { customDomain: null }, { merge: true });
    try { await fb.deleteDoc(fb.doc(fb.db, "domainMappings", tenant.customDomain)); } catch (e) {}
  };

  const handleDelete = async () => {
    setDeleting(true);
    try {
      await onDelete();
    } catch (e) {
      alert("Kunne ikke slette: " + (e.message || e));
      setDeleting(false);
    }
  };

  const bookingEnabled = tenant.publicBookingEnabled !== false; // default ON
  const bookingUrl = tenant.slug ? `https://booking.ooniq.app/${tenant.slug}` : null;

  const toggleBooking = async () => {
    const next = !bookingEnabled;
    await fb.setDoc(fb.doc(fb.db, "tenants", tenant.id), {
      publicBookingEnabled: next,
    }, { merge: true });
    if (tenant.slug) {
      await syncPublicTenant(tenant.id, { ...tenant, publicBookingEnabled: next }, tenant.slug);
    }
  };

  const saveSlug = async () => {
    const newSlug = slugify(slugDraft);
    if (!newSlug) { alert("Ugyldigt slug."); return; }
    if (newSlug === tenant.slug) { setEditingSlug(false); return; }
    // Check collision
    try {
      const existing = await fb.getDoc(fb.doc(fb.db, "publicTenants", newSlug));
      if (existing.exists() && existing.data().tenantId !== tenant.id) {
        alert(`Slug "${newSlug}" er allerede taget af en anden restaurant.`);
        return;
      }
    } catch (e) {}
    await fb.setDoc(fb.doc(fb.db, "tenants", tenant.id), { slug: newSlug }, { merge: true });
    await syncPublicTenant(tenant.id, { ...tenant, slug: newSlug, publicBookingEnabled: bookingEnabled }, tenant.slug);
    setEditingSlug(false);
  };

  React.useEffect(() => {
    const q = fb.query(
      fb.collection(fb.db, "tenants", tenant.id, "activity"),
      fb.orderBy("at", "desc"),
      fb.limit(50),
    );
    const unsub = fb.onSnapshot(q, (snap) => {
      const out = []; snap.forEach(d => out.push({ id: d.id, ...d.data() }));
      setActivity(out);
    }, () => {});
    return () => unsub();
  }, [tenant.id]);

  const resetPwd = async (email) => {
    setBusy(email);
    try {
      await fb.sendPasswordResetEmail(fb.auth, email);
      alert(`Reset-link sendt til ${email}`);
    } catch (e) {
      alert("Kunne ikke sende: " + (e.message || e));
    } finally {
      setBusy(null);
    }
  };

  const addUser = async () => {
    const email = prompt(`Tilføj bruger til ${tenant.name}\n\nEmail:`);
    if (!email) return;
    const password = prompt("Midlertidig adgangskode (mindst 6 tegn):");
    if (!password || password.length < 6) { alert("Adgangskoden skal være mindst 6 tegn."); return; }
    try {
      const secondary = fb.initializeApp(window.FIREBASE_CONFIG, "secondary-" + Date.now());
      const secAuth = fb.getAuth(secondary);
      const cred = await fb.createUserWithEmailAndPassword(secAuth, email.trim(), password);
      await fb.setDoc(fb.doc(fb.db, "users", cred.user.uid), {
        email: email.trim(),
        role: "manager",
        restaurantId: tenant.id,
        createdAt: fb.serverTimestamp(),
      });
      await fb.signOut(secAuth);
      alert(`Bruger ${email} oprettet. Bed dem logge ind og skifte adgangskode.`);
    } catch (e) {
      alert("Kunne ikke oprette bruger: " + (e.message || e));
    }
  };

  return (
    <aside style={{background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 12, padding: 20, alignSelf: 'flex-start', position: 'sticky', top: 18, maxHeight: 'calc(100vh - 100px)', overflow: 'auto'}}>
      <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start'}}>
        <div>
          <div style={{fontSize: 11, color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 700}}>Restaurant</div>
          <h2 style={{fontFamily: 'var(--display)', fontWeight: 800, fontSize: 26, letterSpacing: '-0.03em', margin: '4px 0 4px', lineHeight: 1.1}}>{(tenant.name || tenant.id).toUpperCase()}</h2>
          <div style={{fontSize: 11, color: 'var(--muted)'}}>ID: {tenant.id}</div>
        </div>
        <button className="btn-icon" onClick={onClose}><Icon name="x" size={16}/></button>
      </div>

      <div style={{display: 'flex', gap: 8, marginTop: 16}}>
        <span className={`status-chip ${active ? 'confirmed' : 'finished'}`}>{active ? 'aktiv' : 'pause'}</span>
        <button className="btn btn-soft" style={{fontSize: 11}} onClick={onToggleActive}>
          {active ? 'Sæt på pause' : 'Genaktiver'}
        </button>
      </div>

      <h4 style={{fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--muted)', fontWeight: 700, marginTop: 22, marginBottom: 10}}>Online booking</h4>
      <div style={{padding: 12, background: 'var(--surface-2)', border: '1px solid var(--line)', borderRadius: 10}}>
        <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10}}>
          <div>
            <div style={{fontSize: 13, fontWeight: 600}}>Offentlig booking-side</div>
            <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 2}}>{bookingEnabled ? 'Åben for online bookinger' : 'Lukket — gæster kan ikke booke online'}</div>
          </div>
          <button className={`btn ${bookingEnabled ? 'btn-soft' : 'btn-accent'}`} style={{fontSize: 11}}
            onClick={toggleBooking}>
            {bookingEnabled ? 'Sluk' : 'Tænd'}
          </button>
        </div>
        {editingSlug ? (
          <div style={{display: 'flex', gap: 6}}>
            <input value={slugDraft} onChange={e => setSlugDraft(e.target.value)}
              style={{flex: 1, padding: '6px 8px', fontSize: 13, border: '1px solid var(--line-strong)', borderRadius: 6, background: 'var(--surface)'}}
              placeholder="restaurant-slug" autoFocus/>
            <button className="btn btn-accent" style={{fontSize: 11}} onClick={saveSlug}>Gem</button>
            <button className="btn btn-soft" style={{fontSize: 11}} onClick={() => { setEditingSlug(false); setSlugDraft(tenant.slug || ''); }}>Annuller</button>
          </div>
        ) : (
          <>
            {tenant.slug ? (
              <>
                <div style={{fontSize: 11, color: 'var(--muted)', marginBottom: 4}}>URL</div>
                <div style={{display: 'flex', gap: 6, alignItems: 'center'}}>
                  <a href={bookingUrl} target="_blank" rel="noreferrer"
                    style={{flex: 1, padding: '6px 8px', fontFamily: 'var(--mono)', fontSize: 12, background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 6, textDecoration: 'none', color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}}>
                    {bookingUrl}
                  </a>
                  <button className="btn btn-soft" style={{fontSize: 11}}
                    onClick={() => navigator.clipboard?.writeText(bookingUrl)}>Kopiér</button>
                  <button className="btn btn-soft" style={{fontSize: 11}} onClick={() => setEditingSlug(true)}>Ret</button>
                </div>
              </>
            ) : (
              <button className="btn btn-soft" style={{fontSize: 11, width: '100%', justifyContent: 'center'}}
                onClick={() => { setSlugDraft(slugify(tenant.name || '')); setEditingSlug(true); }}>
                Vælg booking-URL
              </button>
            )}
          </>
        )}
      </div>

      <h4 style={{fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--muted)', fontWeight: 700, marginTop: 22, marginBottom: 10}}>Eget domæne</h4>
      <div style={{padding: 12, background: 'var(--surface-2)', border: '1px solid var(--line)', borderRadius: 10}}>
        {tenant.customDomain && !editingDomain ? (
          <>
            <div style={{fontSize: 11, color: 'var(--muted)', marginBottom: 4}}>Aktivt domæne</div>
            <div style={{display: 'flex', gap: 6, alignItems: 'center', marginBottom: 10}}>
              <a href={`https://${tenant.customDomain}`} target="_blank" rel="noreferrer"
                style={{flex: 1, padding: '6px 8px', fontFamily: 'var(--mono)', fontSize: 12, background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 6, textDecoration: 'none', color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}}>
                https://{tenant.customDomain}
              </a>
              <button className="btn btn-soft" style={{fontSize: 11}} onClick={() => setEditingDomain(true)}>Ret</button>
              <button className="btn btn-soft" style={{fontSize: 11, color: 'var(--danger)'}} onClick={removeDomain}>Fjern</button>
            </div>
            <details style={{fontSize: 12, color: 'var(--muted)'}}>
              <summary style={{cursor: 'pointer', fontWeight: 600, color: 'var(--ink)'}}>Vis DNS-instruktioner</summary>
              <DnsInstructions host={tenant.customDomain}/>
            </details>
          </>
        ) : editingDomain ? (
          <>
            <div style={{fontSize: 12, color: 'var(--muted)', marginBottom: 6}}>
              Skriv det fulde domæne gæsten skal kunne booke på — fx <strong>booking.cafestrand.dk</strong>.
            </div>
            <div style={{display: 'flex', gap: 6, marginBottom: 10}}>
              <input value={domainDraft} onChange={e => setDomainDraft(e.target.value)}
                placeholder="booking.cafestrand.dk"
                style={{flex: 1, padding: '8px 10px', fontSize: 13, border: '1px solid var(--line-strong)', borderRadius: 6, background: 'var(--surface)', fontFamily: 'var(--mono)'}}
                autoFocus/>
              <button className="btn btn-accent" style={{fontSize: 11}} onClick={saveDomain}>Gem</button>
              <button className="btn btn-soft" style={{fontSize: 11}} onClick={() => { setEditingDomain(false); setDomainDraft(tenant.customDomain || ''); }}>Annuller</button>
            </div>
            {domainDraft && <DnsInstructions host={domainDraft}/>}
          </>
        ) : (
          <>
            <div style={{fontSize: 12, color: 'var(--muted)', marginBottom: 8, lineHeight: 1.5}}>
              I stedet for <code>booking.ooniq.app/{tenant.slug}</code> kan restauranten få et eget domæne — f.eks. <code>booking.cafestrand.dk</code>.
            </div>
            <button className="btn btn-soft" style={{width: '100%', justifyContent: 'center', fontSize: 12}}
              onClick={() => setEditingDomain(true)}>
              <Icon name="plus" size={13}/> Tilføj eget domæne
            </button>
          </>
        )}
      </div>

      <h4 style={{fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--muted)', fontWeight: 700, marginTop: 22, marginBottom: 10}}>Brugere</h4>
      {users.length === 0 && <div style={{fontSize: 12, color: 'var(--muted)', padding: 12, background: 'var(--surface-2)', borderRadius: 8}}>Ingen brugere koblet endnu.</div>}
      {users.map(u => (
        <div key={u.id} style={{padding: '10px 12px', background: 'var(--surface-2)', border: '1px solid var(--line)', borderRadius: 8, marginBottom: 6}}>
          <div style={{fontWeight: 600, fontSize: 13}}>{u.email}</div>
          <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 2}}>{u.role || 'manager'} · Sidst inde: {fmtRelative(u.lastLoginAt)}</div>
          <div style={{display: 'flex', gap: 6, marginTop: 8}}>
            <button className="btn btn-soft" style={{fontSize: 11}} disabled={busy === u.email}
              onClick={() => resetPwd(u.email)}>
              <Icon name="mail" size={12}/> {busy === u.email ? 'Sender…' : 'Send reset-link'}
            </button>
          </div>
        </div>
      ))}
      <button className="btn btn-soft" style={{width: '100%', justifyContent: 'center', marginTop: 8}}
        onClick={addUser}>
        <Icon name="plus" size={13}/> Tilføj bruger
      </button>

      <h4 style={{fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--muted)', fontWeight: 700, marginTop: 22, marginBottom: 10}}>Seneste aktivitet</h4>
      {activity.length === 0 && <div style={{fontSize: 12, color: 'var(--muted)', padding: 12, background: 'var(--surface-2)', borderRadius: 8}}>Ingen aktivitet endnu.</div>}
      {activity.map(a => (
        <div key={a.id} style={{padding: '8px 0', borderBottom: '1px solid var(--line)'}}>
          <div style={{display: 'flex', justifyContent: 'space-between', gap: 8, fontSize: 12}}>
            <span style={{fontWeight: 600}}>{labelForActivity(a)}</span>
            <span style={{color: 'var(--muted)', fontSize: 11, whiteSpace: 'nowrap'}}>{fmtRelative(a.at)}</span>
          </div>
          {a.by && <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 2}}>{a.by}</div>}
        </div>
      ))}

      <h4 style={{fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--danger)', fontWeight: 700, marginTop: 28, marginBottom: 10}}>Farezone</h4>
      {!confirmDelete ? (
        <button className="btn btn-ghost" style={{width: '100%', justifyContent: 'center', color: 'var(--danger)', borderColor: 'rgba(224,83,58,0.3)'}}
          onClick={() => setConfirmDelete(true)}>
          <Icon name="x" size={14}/> Slet restaurant
        </button>
      ) : (
        <div style={{padding: 14, background: 'var(--danger-soft)', border: '1px solid rgba(224,83,58,0.3)', borderRadius: 10}}>
          <div style={{fontSize: 13, color: '#6E2114', marginBottom: 8, fontWeight: 600}}>
            Slet "{tenant.name}" permanent?
          </div>
          <div style={{fontSize: 12, color: '#6E2114', marginBottom: 10, lineHeight: 1.5}}>
            Alle reservationer, borde, gæster, gavekort og aktivitetslog forsvinder. Brugernes Firebase Auth-konti slettes ikke automatisk — fjern dem manuelt fra Auth Console hvis nødvendigt.
          </div>
          <div style={{fontSize: 12, color: '#6E2114', marginBottom: 6}}>
            Skriv <strong>{tenant.name}</strong> for at bekræfte:
          </div>
          <input value={deleteText} onChange={e => setDeleteText(e.target.value)}
            placeholder={tenant.name}
            style={{width: '100%', padding: '8px 10px', fontSize: 13, border: '1px solid rgba(224,83,58,0.4)', borderRadius: 6, background: 'var(--surface)', marginBottom: 10}}/>
          <div style={{display: 'flex', gap: 6}}>
            <button className="btn btn-soft" style={{flex: 1, justifyContent: 'center', fontSize: 12}}
              onClick={() => { setConfirmDelete(false); setDeleteText(''); }}
              disabled={deleting}>Annuller</button>
            <button className="btn"
              style={{flex: 1, justifyContent: 'center', fontSize: 12, background: 'var(--danger)', color: '#fff'}}
              disabled={deleteText !== tenant.name || deleting}
              onClick={handleDelete}>
              {deleting ? 'Sletter…' : 'Slet permanent'}
            </button>
          </div>
        </div>
      )}
    </aside>
  );
}

function labelForActivity(a) {
  switch (a.kind) {
    case 'login': return `Login: ${a.email || a.by}`;
    case 'reservation_created': return `Ny reservation: ${a.name} (${a.pax} pers)`;
    case 'reservation_cancelled': return `Aflyst: ${a.name} (${a.pax} pers)`;
    case 'reservation_status': return `Status ændret: ${a.id} → ${a.status}`;
    case 'walkin': return `Walk-in: ${a.name} (${a.pax} pers)`;
    case 'waitlist_seated': return `Sat til bords (venteliste): ${a.name}`;
    default: return a.kind;
  }
}

function fmtRelative(ts) {
  if (!ts) return '—';
  const d = ts.toDate ? ts.toDate() : (ts instanceof Date ? ts : new Date(ts));
  if (isNaN(d)) return '—';
  const diff = (Date.now() - d.getTime()) / 1000;
  if (diff < 60) return 'lige nu';
  if (diff < 3600) return `${Math.round(diff/60)} min siden`;
  if (diff < 86400) return `${Math.round(diff/3600)} t siden`;
  if (diff < 86400 * 30) return `${Math.round(diff/86400)} d siden`;
  return d.toLocaleDateString('da-DK');
}

function CreateRestaurantModal({ onClose }) {
  const fb = window.fb;
  const [name, setName] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [pwd, setPwd] = React.useState('');
  const [seed, setSeed] = React.useState(true);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');

  const submit = async () => {
    setError('');
    if (!name) return setError('Navn mangler.');
    if (!email) return setError('Email mangler.');
    if (!pwd || pwd.length < 6) return setError('Adgangskoden skal være mindst 6 tegn.');
    setBusy(true);
    try {
      // 1. Generate tenant id + slug from name. Slug is the user-facing
      //    booking URL piece; tenant id is the random opaque key.
      const baseSlug = slugify(name);
      const tenantId = baseSlug + '-' + Math.random().toString(36).slice(2,6);
      // Pick a unique slug — fall back to tenantId if base is taken
      let slug = baseSlug;
      try {
        const taken = await fb.getDoc(fb.doc(fb.db, "publicTenants", slug));
        if (taken.exists()) slug = tenantId;
      } catch (e) { slug = tenantId; }

      // 2. Create the tenant document FIRST so rules see it during user creation
      await fb.setDoc(fb.doc(fb.db, "tenants", tenantId), {
        name, active: true, ownerEmail: email,
        slug,
        publicBookingEnabled: true,
        createdAt: fb.serverTimestamp(),
        lastActivityAt: fb.serverTimestamp(),
      });
      // Mirror to publicTenants so booking.ooniq.app/{slug} resolves
      await fb.setDoc(fb.doc(fb.db, "publicTenants", slug), {
        tenantId, name, enabled: true, defaultDurationMin: 105,
      });

      // 3. Create the auth user using a secondary app so we don't get logged out
      const secondary = fb.initializeApp(window.FIREBASE_CONFIG, "create-" + Date.now());
      const secAuth = fb.getAuth(secondary);
      const cred = await fb.createUserWithEmailAndPassword(secAuth, email.trim(), pwd);
      await fb.setDoc(fb.doc(fb.db, "users", cred.user.uid), {
        email: email.trim(),
        role: "manager",
        restaurantId: tenantId,
        createdAt: fb.serverTimestamp(),
      });
      await fb.signOut(secAuth);

      // 4. Optionally seed demo data
      if (seed) {
        await window.seedTenant(tenantId);
      }

      onClose();
      alert(`Restauranten "${name}" er oprettet.\n\nFørste bruger: ${email}\nMidlertidig adgangskode er sat — bed dem logge ind og skifte den.`);
    } catch (e) {
      setError(e.message || String(e));
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" style={{width: 560}} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3>NY RESTAURANT</h3>
          <p>Opret en restaurant og dens første bruger.</p>
        </div>
        <div className="modal-body">
          <div className="field">
            <label>Restaurantens navn</label>
            <input value={name} onChange={e => setName(e.target.value)} placeholder="f.eks. Restaurant Hjem" autoFocus/>
          </div>
          <div className="field">
            <label>Email til første bruger (ejer / manager)</label>
            <input type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="dig@restauranten.dk"/>
          </div>
          <div className="field">
            <label>Midlertidig adgangskode (mindst 6 tegn)</label>
            <input type="text" value={pwd} onChange={e => setPwd(e.target.value)} placeholder="Vælg en kode — del den sikkert med brugeren"/>
            <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 6}}>
              Brugeren kan selv ændre koden via „Glemt adgangskode“ på loginsiden.
            </div>
          </div>
          <div className="field">
            <label>Demo-data</label>
            <div style={{display: 'flex', gap: 6}}>
              <button className={`chip ${seed ? 'active' : ''}`} onClick={() => setSeed(true)}>Start med demo</button>
              <button className={`chip ${!seed ? 'active' : ''}`} onClick={() => setSeed(false)}>Tom restaurant</button>
            </div>
          </div>
          {error && <div className="auth-error">{error}</div>}
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose}>Annuller</button>
          <button className="btn btn-accent" onClick={submit} disabled={busy}>
            <Icon name="check" size={14}/> {busy ? 'Opretter…' : 'Opret restaurant'}
          </button>
        </div>
      </div>
    </div>
  );
}

function DnsInstructions({ host }) {
  if (!host) return null;
  // Firebase Hosting provisions SSL for a custom domain via two A records.
  // The exact IPs are stable values published in Firebase docs.
  const records = [
    { type: 'A', name: host, value: '199.36.158.100' },
    { type: 'A', name: host, value: '199.36.158.101' },
  ];
  const copy = (s) => navigator.clipboard?.writeText(s);
  return (
    <div style={{marginTop: 12, padding: 12, background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 8}}>
      <div style={{fontSize: 11, color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 700, marginBottom: 8}}>
        DNS-records hos restaurantens domæneudbyder
      </div>
      <div style={{fontSize: 12, color: 'var(--ink-2)', marginBottom: 10, lineHeight: 1.5}}>
        Tilføj følgende A-records til <strong>{host.split('.').slice(-2).join('.')}</strong> hos DNS-udbyderen (Simply, Gratisdns, Cloudflare osv.):
      </div>
      <div style={{display: 'grid', gridTemplateColumns: '40px 1fr 1fr auto', gap: 4, fontSize: 11, color: 'var(--muted)', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 4}}>
        <span>Type</span><span>Navn / host</span><span>Værdi</span><span></span>
      </div>
      {records.map((r, i) => (
        <div key={i} style={{display: 'grid', gridTemplateColumns: '40px 1fr 1fr auto', gap: 4, alignItems: 'center', padding: '6px 0', fontSize: 12, fontFamily: 'var(--mono)', borderTop: i ? '1px solid var(--line)' : 0}}>
          <strong>{r.type}</strong>
          <span style={{overflow: 'hidden', textOverflow: 'ellipsis'}}>{r.name}</span>
          <span>{r.value}</span>
          <button className="btn btn-soft" style={{fontSize: 10, padding: '3px 6px'}} onClick={() => copy(r.value)}>Kopiér</button>
        </div>
      ))}
      <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 10, lineHeight: 1.5}}>
        Når DNS er sat: kontakt support hos Seatiq for at få domænet tilføjet i Firebase Hosting (kræver browser-adgang til Console for SSL-cert provisioning). Når det er godkendt, peger {host} på restaurantens booking-side automatisk.
      </div>
    </div>
  );
}

function slugify(s) {
  return String(s).toLowerCase()
    .replace(/[æä]/g, 'ae').replace(/[å]/g, 'aa').replace(/ø|ö/g, 'o').replace(/ü/g, 'u')
    .replace(/[^a-z0-9]+/g, '')
    .slice(0, 40) || 'restaurant';
}

window.AdminApp = AdminApp;
