// Login page — MedLink. Two-pane auth with role picker + 2FA step.

// ---- WebAuthn helpers (biometric login: Face ID / Touch ID / Windows Hello) ----
const webAuthnSupported = () =>
  typeof window !== "undefined" &&
  !!window.PublicKeyCredential &&
  !!window.crypto?.subtle &&
  typeof navigator.credentials?.create === "function";

const BIO_STORAGE_KEY = "medlink.bio.cred";
const b64u = {
  enc: (buf) => btoa(String.fromCharCode(...new Uint8Array(buf))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""),
  dec: (s) => Uint8Array.from(atob(s.replace(/-/g, "+").replace(/_/g, "/") + "==".slice(0, (4 - s.length % 4) % 4)), (c) => c.charCodeAt(0)),
};
const randomBytes = (n = 32) => {
  const b = new Uint8Array(n);
  crypto.getRandomValues(b);
  return b;
};

const registerBiometric = async (role) => {
  const challenge = randomBytes(32);
  const userId = randomBytes(16);
  const cred = await navigator.credentials.create({
    publicKey: {
      challenge,
      rp: { name: "MedLink", id: location.hostname },
      user: { id: userId, name: `medlink-${role}`, displayName: `MedLink ${role}` },
      pubKeyCredParams: [{ type: "public-key", alg: -7 }, { type: "public-key", alg: -257 }],
      authenticatorSelection: { userVerification: "preferred", residentKey: "preferred" },
      timeout: 60000,
      attestation: "none",
    },
  });
  if (!cred) throw new Error("no credential");
  const rawId = b64u.enc(cred.rawId);
  const stored = { id: rawId, role, enrolledAt: new Date().toISOString() };
  localStorage.setItem(BIO_STORAGE_KEY, JSON.stringify(stored));
  return stored;
};

const authenticateBiometric = async () => {
  const raw = localStorage.getItem(BIO_STORAGE_KEY);
  if (!raw) throw new Error("not enrolled");
  const stored = JSON.parse(raw);
  const challenge = randomBytes(32);
  const assertion = await navigator.credentials.get({
    publicKey: {
      challenge,
      rpId: location.hostname,
      allowCredentials: [{ id: b64u.dec(stored.id), type: "public-key" }],
      userVerification: "preferred",
      timeout: 60000,
    },
  });
  if (!assertion) throw new Error("no assertion");
  return stored;
};

const clearBiometric = () => { localStorage.removeItem(BIO_STORAGE_KEY); };

const LoginPage = ({ onLogin }) => {
  const [step, setStep] = React.useState("credentials"); // credentials | otp
  const [role, setRole] = React.useState("pflege");
  const [arztId, setArztId] = React.useState("schn");
  const [email, setEmail] = React.useState("maria.lehmann@rosenhof.de");
  const [password, setPassword] = React.useState("••••••••••");
  const [otp, setOtp] = React.useState(["","","","","",""]);
  const [bioStatus, setBioStatus] = React.useState(""); // "" | "busy" | "error"
  const [bioMsg, setBioMsg] = React.useState("");
  const [bioAvail, setBioAvail] = React.useState(false);
  const [bioEnrolled, setBioEnrolled] = React.useState(false);
  const inputs = React.useRef([]);

  React.useEffect(() => {
    if (!webAuthnSupported()) return;
    setBioAvail(true);
    setBioEnrolled(!!localStorage.getItem(BIO_STORAGE_KEY));
    // Falls Platform-Authenticator (Face ID / TouchID) verfügbar: nachgewiesen prüfen
    try {
      window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable?.().then((avail) => {
        setBioAvail(avail === true);
      });
    } catch {}
  }, []);

  const handleBiometric = async () => {
    if (bioStatus === "busy") return;
    setBioStatus("busy");
    setBioMsg("");
    try {
      if (bioEnrolled) {
        const stored = await authenticateBiometric();
        setBioStatus("");
        setBioMsg("Erfolg");
        setTimeout(() => onLogin(stored.role || role, { arztId }), 300);
      } else {
        await registerBiometric(role);
        setBioEnrolled(true);
        setBioStatus("");
        setBioMsg("Biometrie aktiviert — bitte erneut tippen");
      }
    } catch (err) {
      setBioStatus("error");
      setBioMsg(err?.message?.includes("not enrolled")
        ? "Noch nicht eingerichtet"
        : err?.name === "NotAllowedError"
          ? "Abgebrochen"
          : "Fehler bei der Biometrie");
      setTimeout(() => { setBioStatus(""); setBioMsg(""); }, 2500);
    }
  };

  const roleMap = [
    { id: "pflege",    nm: "Pflegekraft / Leitung", sub: "Heim-Portal",         icon: "home" },
    { id: "arzt",      nm: "Arzt",                   sub: "Multi-Heim Queue",    icon: "stethoscope" },
    { id: "apotheke",  nm: "Apotheke",               sub: "Rezept-Eingang",      icon: "pill" },
    { id: "therapeut", nm: "Therapeut",              sub: "Physio · Ergo · Logo",icon: "activity" },
    { id: "admin",     nm: "Administrator",          sub: "MedLink Betrieb",     icon: "shield" },
  ];

  const onOtpChange = (i, v) => {
    const next = [...otp];
    next[i] = v.slice(-1);
    setOtp(next);
    if (v && i < 5) inputs.current[i+1]?.focus();
  };

  const submit = (e) => {
    e.preventDefault();
    if (step === "credentials") setStep("otp");
    else onLogin(role, { arztId });
  };

  return (
    <div className="auth">
      <aside className="auth-art">
        <div className="grid-bg" />
        <div className="brand-big">
          <div className="mark"><Icon name="heart" size={20} /></div>
          <div>
            <div className="name">MedLink</div>
            <div style={{fontSize: 12, color: "var(--fg-muted)"}}>Zentrale Kommunikations- & Verordnungsplattform</div>
          </div>
        </div>

        <div className="auth-pitch">
          <div className="eyebrow">Für Alten- und Pflegeheime</div>
          <h1>Schluss mit Telefon, Fax und WhatsApp.</h1>
          <p>Strukturierte Verordnungen zwischen Pflege, Arzt und Apotheke — dokumentiert, verschlüsselt und DSGVO-konform auf deutschen Servern.</p>
          <ul>
            <li><span className="ck"><Icon name="check" size={11} /></span> 30 Sekunden bis zur Medikamentenanforderung</li>
            <li><span className="ck"><Icon name="check" size={11} /></span> Ein-Tipp-Freigabe durch den Arzt zwischen Patienten</li>
            <li><span className="ck"><Icon name="check" size={11} /></span> Lückenloses Audit-Log · Art. 30 DSGVO</li>
            <li><span className="ck"><Icon name="check" size={11} /></span> Hosting in Nürnberg · TLS 1.3 · AES-256 at rest</li>
          </ul>

          <div className="preview-card">
            <div className="row"><span className="left">Offene Anfragen heute</span><span className="mono">18</span></div>
            <div className="row"><span className="left">Ø Freigabe-Zeit</span><span className="mono" style={{color: "var(--success)"}}>94 Min ↓</span></div>
            <div className="row"><span className="left">Angebundene Heime</span><span className="mono">4 · 247 Bewohner</span></div>
            <div className="row"><span className="left">System-Status</span>
              <span className="row" style={{gap: 6, fontSize: 11}}>
                <span style={{width: 6, height: 6, borderRadius: "50%", background: "var(--success)", boxShadow: "0 0 0 3px var(--success-tint)"}} />
                Alle Dienste erreichbar
              </span>
            </div>
          </div>
        </div>

        <div className="auth-foot">
          <span className="chip"><Icon name="shield" size={11} /> DSGVO · BSI-Grundschutz</span>
          <span className="chip"><Icon name="home" size={11} /> Hetzner DE · Nürnberg</span>
          <span style={{marginLeft: "auto"}}>v4.2.1 · © 2026 MedLink GmbH</span>
        </div>
      </aside>

      <section className="auth-form">
        <div className="head">
          <h2>{step === "credentials" ? "Anmelden" : "Zwei-Faktor-Bestätigung"}</h2>
          <div className="sub">
            {step === "credentials"
              ? "Wählen Sie Ihre Rolle und melden Sie sich an."
              : <>Code aus Ihrer Authenticator-App (6 Stellen) · <a href="#" style={{color: "var(--accent)"}}>Hilfe</a></>}
          </div>
        </div>

        {step === "credentials" && (
          <form onSubmit={submit}>
            <div className="field">
              <label>Rolle</label>
              <div className="role-grid">
                {roleMap.map(r => (
                  <button type="button" key={r.id} className={`role-card ${role === r.id ? "active" : ""}`} onClick={() => setRole(r.id)}>
                    <div className="row1">
                      <span className="ic"><Icon name={r.icon} size={14} /></span>
                      <span className="arrow"><Icon name="chevronRight" size={12} /></span>
                    </div>
                    <span className="nm">{r.nm}</span>
                    <span className="sub">{r.sub}</span>
                  </button>
                ))}
              </div>
            </div>

            {role === "arzt" && (
              <div className="field">
                <label>Fachrichtung / Arztprofil</label>
                <div className="doc-grid">
                  {(window.DOCTORS || []).map(d => {
                    const tone = { Hausarzt: "teal", Internist: "amber", Geriater: "teal", Nervenarzt: "violet", Palliativ: "rose", Urologe: "indigo" }[d.spec] || "teal";
                    const isSel = arztId === d.id;
                    return (
                      <button
                        type="button"
                        key={d.id}
                        className={`doc-card ${isSel ? "active" : ""}`}
                        data-tone={tone}
                        onClick={() => setArztId(d.id)}
                      >
                        <div className="doc-card-head">
                          <span className="doc-mark" data-tone={tone}>
                            {d.spec === "Hausarzt" ? "H" : d.spec === "Internist" ? "I" : d.spec === "Geriater" ? "G" : d.spec === "Nervenarzt" ? "N" : d.spec === "Palliativ" ? "P" : "U"}
                          </span>
                          <span className="doc-spec">{d.spec}</span>
                          {isSel && <Icon name="check" size={12} className="doc-check" />}
                        </div>
                        <div className="doc-name">{d.name.replace("Dr. med. ", "Dr. ")}</div>
                        <div className="doc-sub">{d.heims.length} Heime · {d.interval || "täglich"}</div>
                      </button>
                    );
                  })}
                </div>
              </div>
            )}

            <div className="field">
              <label>E-Mail</label>
              <input type="email" value={email} onChange={e => setEmail(e.target.value)} autoComplete="email" />
            </div>
            <div className="field">
              <label>Passwort <a href="#">Vergessen?</a></label>
              <input type="password" value={password} onChange={e => setPassword(e.target.value)} autoComplete="current-password" />
            </div>

            <button type="submit" className="btn-primary">
              Weiter <Icon name="arrowRight" size={13} />
            </button>

            <button
              type="button"
              className="demo-cta"
              onClick={() => {
                onLogin("pflege");
                setTimeout(() => window.dispatchEvent(new CustomEvent("medlink:demoStart")), 120);
              }}
            >
              <Icon name="play" size={12} />
              <span>Geführte Demo-Tour starten</span>
              <span className="pill">20 Sek.</span>
            </button>

            {bioAvail && (
              <>
                <div className="divider">Biometrisch</div>
                <button
                  type="button"
                  className={`bio-btn ${bioStatus}`}
                  onClick={handleBiometric}
                  disabled={bioStatus === "busy"}
                >
                  <span className="bio-ic"><Icon name="shield" size={14} /></span>
                  <span className="bio-body">
                    <span className="bio-title">
                      {bioEnrolled ? "Mit Face ID / Touch ID anmelden" : "Biometrie einrichten"}
                    </span>
                    <span className="bio-sub">
                      {bioStatus === "busy" ? "Authenticator wird angefragt …"
                        : bioMsg ? bioMsg
                        : bioEnrolled ? "Tippen Sie zum Anmelden ohne Passwort"
                        : "Einmal einrichten, danach mit einem Tipp"}
                    </span>
                  </span>
                  {bioEnrolled && !bioStatus && (
                    <span className="bio-pill">
                      <Icon name="check" size={10} /> aktiv
                    </span>
                  )}
                </button>
                {bioEnrolled && (
                  <button
                    type="button"
                    className="bio-reset"
                    onClick={() => { clearBiometric(); setBioEnrolled(false); setBioMsg("Zurückgesetzt"); setTimeout(() => setBioMsg(""), 1500); }}
                  >
                    Biometrie zurücksetzen
                  </button>
                )}
              </>
            )}

            <div className="divider">SSO</div>
            <button type="button" className="btn-primary" style={{background: "var(--bg-raised)", color: "var(--fg)", border: "1px solid var(--border-strong)", boxShadow: "none"}}>
              <Icon name="shield" size={13} /> KIM / TI-Konnektor
            </button>

            <div className="auth-legal">
              Mit der Anmeldung stimmen Sie unseren <a href="#">Nutzungsbedingungen</a> und der <a href="#">Datenschutzerklärung</a> zu.<br />
              AVV nach Art. 28 DSGVO liegt zwischen Mandant und MedLink GmbH vor.
            </div>
          </form>
        )}

        {step === "otp" && (
          <form onSubmit={submit}>
            <div className="field">
              <label>6-stelliger Code</label>
              <div className="otp-row">
                {otp.map((v, i) => (
                  <input
                    key={i}
                    ref={el => inputs.current[i] = el}
                    inputMode="numeric"
                    maxLength="1"
                    value={v}
                    onChange={e => onOtpChange(i, e.target.value)}
                    autoFocus={i === 0}
                  />
                ))}
              </div>
              <div style={{fontSize: 11, color: "var(--fg-subtle)"}}>
                Code erneuert sich alle 30 Sekunden · <a href="#" style={{color: "var(--accent)"}}>Hardware-Token verwenden</a>
              </div>
            </div>
            <button type="submit" className="btn-primary">Anmelden <Icon name="check" size={13} /></button>
            <button type="button" className="btn-primary" onClick={() => setStep("credentials")} style={{marginTop: 8, background: "transparent", color: "var(--fg-muted)", border: "1px solid var(--border)", boxShadow: "none"}}>
              <Icon name="back" size={13} /> Zurück
            </button>
            <div className="auth-legal">
              Angemeldet als <strong>{email}</strong> · Rolle: <strong>{roleMap.find(r => r.id === role)?.nm}</strong>
            </div>
          </form>
        )}
      </section>
    </div>
  );
};

window.LoginPage = LoginPage;
