/* AuthGate — wraps the app, only renders children once a Firebase user is
   signed in and their /users/{uid} doc + tenant doc are loaded.
   For /admin we require role === 'admin'. */

const AuthCtx = React.createContext(null);
function useAuth() { return React.useContext(AuthCtx); }

function AuthGate({ requireRole = null, children }) {
  const fb = window.fb;
  const [phase, setPhase] = React.useState("loading"); // loading | login | ready | denied | deactivated | error
  const [user, setUser] = React.useState(null);
  const [userDoc, setUserDoc] = React.useState(null);
  const [tenantDoc, setTenantDoc] = React.useState(null);
  const [errorMsg, setErrorMsg] = React.useState("");

  React.useEffect(() => {
    let cancelled = false;
    const unsub = fb.onAuthStateChanged(fb.auth, async (u) => {
      if (cancelled) return;
      if (!u) {
        setUser(null); setUserDoc(null); setTenantDoc(null);
        setPhase("login");
        return;
      }
      setUser(u);
      try {
        const uSnap = await fb.getDoc(fb.doc(fb.db, "users", u.uid));
        if (!uSnap.exists()) {
          // Auth user exists but no user doc — locked out until admin assigns
          setErrorMsg("Din konto er endnu ikke knyttet til en restaurant. Kontakt din administrator.");
          setPhase("denied");
          return;
        }
        const ud = uSnap.data();
        setUserDoc(ud);

        if (requireRole === "admin") {
          if (ud.role !== "admin") {
            setErrorMsg("Kun administratorer har adgang til denne side.");
            setPhase("denied");
            return;
          }
          setTenantDoc(null);
          // record login (non-blocking)
          fb.setDoc(fb.doc(fb.db, "users", u.uid), { lastLoginAt: fb.serverTimestamp() }, { merge: true }).catch(() => {});
          setPhase("ready");
          return;
        }

        // Manager / staff path: must have a tenantId and tenant must be active
        if (!ud.restaurantId) {
          setErrorMsg("Din konto er ikke koblet til en restaurant endnu.");
          setPhase("denied");
          return;
        }
        const tSnap = await fb.getDoc(fb.doc(fb.db, "tenants", ud.restaurantId));
        if (!tSnap.exists()) {
          setErrorMsg("Restauranten kunne ikke findes.");
          setPhase("denied");
          return;
        }
        const td = { id: tSnap.id, ...tSnap.data() };
        if (td.active === false) {
          setErrorMsg("Din restaurant er deaktiveret. Kontakt support.");
          setPhase("deactivated");
          return;
        }
        setTenantDoc(td);
        // record login + activity
        fb.setDoc(fb.doc(fb.db, "users", u.uid), { lastLoginAt: fb.serverTimestamp() }, { merge: true }).catch(() => {});
        fb.addDoc(fb.collection(fb.db, "tenants", td.id, "activity"), {
          kind: "login", email: ud.email || u.email, at: fb.serverTimestamp(),
        }).catch(() => {});
        fb.setDoc(fb.doc(fb.db, "tenants", td.id), { lastActivityAt: fb.serverTimestamp() }, { merge: true }).catch(() => {});
        setPhase("ready");
      } catch (e) {
        console.error(e);
        setErrorMsg(e.message || String(e));
        setPhase("error");
      }
    });
    return () => { cancelled = true; unsub(); };
  }, [requireRole]);

  const signOutHandler = () => fb.signOut(fb.auth);

  if (phase === "loading") return <LoadingScreen/>;
  if (phase === "login")   return <LoginScreen mode={requireRole === "admin" ? "admin" : "user"}/>;
  if (phase === "denied" || phase === "deactivated" || phase === "error") {
    return <BlockedScreen message={errorMsg} onSignOut={signOutHandler}/>;
  }

  return (
    <AuthCtx.Provider value={{ user, userDoc, tenantDoc, tenantId: tenantDoc?.id || null, signOut: signOutHandler }}>
      {children}
    </AuthCtx.Provider>
  );
}

function LoadingScreen() {
  return (
    <div className="auth-shell">
      <div className="auth-card">
        <div className="auth-brand">SEATIQ<span className="dot">.</span></div>
        <div className="auth-spinner"/>
        <div className="auth-loading">Indlæser…</div>
      </div>
    </div>
  );
}

function LoginScreen({ mode = "user" }) {
  const fb = window.fb;
  const [email, setEmail] = React.useState("");
  const [pwd, setPwd] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState("");
  const [resetSent, setResetSent] = React.useState(false);

  const submit = async (e) => {
    e?.preventDefault?.();
    setError(""); setBusy(true);
    try {
      await fb.signInWithEmailAndPassword(fb.auth, email.trim(), pwd);
    } catch (err) {
      const code = err?.code || "";
      const map = {
        "auth/invalid-credential": "Forkert email eller adgangskode.",
        "auth/invalid-email": "Ugyldig email.",
        "auth/user-not-found": "Brugeren findes ikke.",
        "auth/wrong-password": "Forkert adgangskode.",
        "auth/too-many-requests": "For mange forsøg — prøv igen om lidt.",
      };
      setError(map[code] || err.message || "Login fejlede.");
    } finally {
      setBusy(false);
    }
  };

  const sendReset = async () => {
    if (!email) { setError("Indtast email først."); return; }
    setError("");
    try {
      await fb.sendPasswordResetEmail(fb.auth, email.trim());
      setResetSent(true);
    } catch (err) {
      setError(err.message || "Kunne ikke sende email.");
    }
  };

  return (
    <div className="auth-shell">
      <form className="auth-card" onSubmit={submit}>
        <div className="auth-brand">SEATIQ<span className="dot">.</span></div>
        <div className="auth-eyebrow">{mode === "admin" ? "Administrator" : "Restaurant log-in"}</div>
        <h1 className="auth-title">{mode === "admin" ? "ADMIN" : "VELKOMMEN TILBAGE"}</h1>
        <p className="auth-sub">
          {mode === "admin"
            ? "Kun dedikerede administratorer kan logge ind her."
            : "Log ind for at se din restaurants reservationer, gæster og borde."}
        </p>

        <div className="auth-field">
          <label>Email</label>
          <input type="email" autoComplete="email" autoFocus
            value={email} onChange={e => setEmail(e.target.value)}
            placeholder="dig@restauranten.dk" />
        </div>
        <div className="auth-field">
          <label>Adgangskode</label>
          <input type="password" autoComplete="current-password"
            value={pwd} onChange={e => setPwd(e.target.value)}
            placeholder="••••••••" />
        </div>

        {error && <div className="auth-error">{error}</div>}
        {resetSent && <div className="auth-info">Vi har sendt et link til at nulstille din adgangskode.</div>}

        <button className="btn btn-primary auth-submit" type="submit" disabled={busy}>
          {busy ? "Logger ind…" : (mode === "admin" ? "Log ind som admin" : "Log ind")}
        </button>

        <button type="button" className="auth-link" onClick={sendReset}>
          Glemt adgangskode?
        </button>

        {mode === "admin" && (
          <div className="auth-footer">
            <a href="/">← Til restaurant-login</a>
          </div>
        )}
        {mode !== "admin" && (
          <div className="auth-footer">
            <a href="/admin">Administrator-login →</a>
          </div>
        )}
      </form>
    </div>
  );
}

function BlockedScreen({ message, onSignOut }) {
  return (
    <div className="auth-shell">
      <div className="auth-card">
        <div className="auth-brand">SEATIQ<span className="dot">.</span></div>
        <h1 className="auth-title" style={{fontSize: 32}}>ADGANG SPÆRRET</h1>
        <p className="auth-sub">{message}</p>
        <button className="btn btn-soft auth-submit" onClick={onSignOut}>Log ud</button>
      </div>
    </div>
  );
}

window.AuthGate = AuthGate;
window.useAuth = useAuth;
window.LoginScreen = LoginScreen;
