// auth.jsx — Sign in / Sign up screens (wired to MedSync backend)

const { useState: useStateA, useEffect: useEffectA, useRef: useRefA } = React;

async function postAuth(path, body) {
  const r = await fetch(path, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify(body),
  });
  let data = null;
  try { data = await r.json(); } catch (_) {}
  if (!r.ok) {
    const msg = (data && (data.detail || data.message)) || `Request failed (${r.status})`;
    throw new Error(typeof msg === "string" ? msg : "Sign-in failed");
  }
  return data || {};
}

function applyAuthSuccess(data) {
  // Update window globals (used by api.jsx) so subsequent fetches carry the
  // bearer + active account; the parent screen also passes the payload to the
  // store via onSignIn(payload) so React state stays in sync.
  if (data && data.token && window.MSApi) window.MSApi.setToken(data.token);
  if (data && data.active_account && data.active_account.id && window.MSApi) {
    window.MSApi.setAccountId(data.active_account.id);
  }
  if (data && data.doctor) window._currentDoctor = data.doctor;
  if (data && data.active_account) window._currentAccount = data.active_account;
  if (data && data.accounts) window._currentAccounts = data.accounts;
  if (data && data.active_role) window._currentRole = data.active_role;
}

function AuthShell({ children, side }) {
  return (
    <div className="ms-auth">
      <div className="ms-auth-form">
        <div className="ms-auth-brand">
          <div className="ms-brand-mark" style={{width: 36, height: 36, borderRadius: 10}}>
            <Icon.Logo size={30}/>
          </div>
          <div>
            <div style={{fontWeight: 600, fontSize: 16, letterSpacing: "-0.01em"}}>MedSync</div>
            <div style={{fontSize: 11.5, color: "var(--ink-4)"}}>Clinic operating system</div>
          </div>
        </div>
        <div className="ms-auth-card">
          {children}
        </div>
        <div className="ms-auth-foot">
          <span>HIPAA compliant · SOC 2 Type II</span>
          <span>·</span>
          <a href="#">Help</a>
          <a href="#">Privacy</a>
        </div>
      </div>
      <div className="ms-auth-side">
        {side}
      </div>
    </div>
  );
}

function GoogleSignInButton({ onCredential, onError }) {
  const hostRef = useRefA(null);
  const credRef = useRefA(onCredential);
  const errRef = useRefA(onError);
  const [ready, setReady] = useStateA(false);
  const [missing, setMissing] = useStateA(false);

  // Keep latest callbacks without re-initializing GSI.
  useEffectA(() => { credRef.current = onCredential; }, [onCredential]);
  useEffectA(() => { errRef.current = onError; }, [onError]);

  useEffectA(() => {
    let cancelled = false;
    let attempts = 0;
    const tick = () => {
      if (cancelled) return;
      const clientId = window.MS_GOOGLE_CLIENT_ID;
      if (!clientId) {
        if (attempts++ > 50) { setMissing(true); return; }
        setTimeout(tick, 100);
        return;
      }
      if (!(window.google && window.google.accounts && window.google.accounts.id)) {
        if (attempts++ > 80) { setMissing(true); return; }
        setTimeout(tick, 100);
        return;
      }
      try {
        if (window.__msGsiInitedFor !== clientId) {
          window.google.accounts.id.initialize({
            client_id: clientId,
            callback: (resp) => {
              const cb = credRef.current;
              const er = errRef.current;
              if (resp && resp.credential) cb && cb(resp.credential);
              else er && er("Google did not return a credential.");
            },
            ux_mode: "popup",
            auto_select: false,
          });
          window.__msGsiInitedFor = clientId;
        }
        if (hostRef.current) {
          hostRef.current.innerHTML = "";
          window.google.accounts.id.renderButton(hostRef.current, {
            type: "standard",
            theme: "outline",
            size: "large",
            text: "continue_with",
            shape: "pill",
            logo_alignment: "left",
            width: 360,
          });
          setReady(true);
        }
      } catch (e) {
        const er = errRef.current;
        er && er(String(e && e.message || e));
      }
    };
    tick();
    return () => { cancelled = true; };
  }, []);

  if (missing) {
    return (
      <div style={{padding: "10px 12px", borderRadius: 10, background: "var(--bg-soft)", border: "1px dashed var(--line-strong)", fontSize: 12.5, color: "var(--ink-4)", textAlign: "center"}}>
        Google sign-in is not configured. Set <span className="mono">GOOGLE_CLIENT_ID</span> on the server.
      </div>
    );
  }

  return (
    <div style={{display: "flex", justifyContent: "center", minHeight: 44}}>
      <div ref={hostRef} style={{visibility: ready ? "visible" : "hidden"}}/>
    </div>
  );
}

function SignIn({ onSignIn, onSwitch }) {
  const [email, setEmail] = useStateA("");
  const [password, setPassword] = useStateA("");
  const [showPw, setShowPw] = useStateA(false);
  const [remember, setRemember] = useStateA(true);
  const [pending, setPending] = useStateA(false);
  const [error, setError] = useStateA("");

  const finish = (data) => { applyAuthSuccess(data); onSignIn(data); };

  async function handleGoogle(credential) {
    setError("");
    setPending(true);
    try {
      const data = await postAuth("/api/auth/google", { credential });
      finish(data);
    } catch (e) {
      setError(e.message || "Google sign-in failed.");
    } finally {
      setPending(false);
    }
  }

  async function handlePassword(e) {
    e.preventDefault();
    if (!email || !password) {
      setError("Enter your email and password.");
      return;
    }
    setError("");
    setPending(true);
    try {
      const data = await postAuth("/api/auth/login", { email, password });
      finish(data);
    } catch (err) {
      setError(err.message || "Sign-in failed.");
    } finally {
      setPending(false);
    }
  }

  return (
    <AuthShell
      side={
        <div className="ms-auth-pitch">
          <div className="eyebrow" style={{color: "rgba(255,255,255,0.7)"}}>MedSync for care teams</div>
          <h1 className="h1" style={{color: "white", fontSize: 36, marginTop: 12, lineHeight: 1.15}}>Clinical work,<br/>kept in sync.</h1>
          <p style={{color: "rgba(255,255,255,0.78)", fontSize: 15, lineHeight: 1.6, marginTop: 16, maxWidth: 440}}>MedSync records visits, creates transcripts and clinical notes, manages patients, appointments, notifications, and follow-ups in one workspace. Compliance is built in with encrypted PHI, audit logging, consent checks, and HIPAA-ready workflows.</p>
          <div className="ms-auth-pitch-stats">
            <div><div className="ms-auth-stat-num">AI</div><div className="ms-auth-stat-label">Transcription and notes</div></div>
            <div><div className="ms-auth-stat-num">PHI</div><div className="ms-auth-stat-label">Encrypted at rest</div></div>
            <div><div className="ms-auth-stat-num">HIPAA</div><div className="ms-auth-stat-label">Audit-first design</div></div>
          </div>
        </div>
      }
    >
      <div>
        <h1 className="h1" style={{fontSize: 26}}>Welcome back</h1>
        <div style={{color: "var(--ink-3)", marginTop: 6, fontSize: 14}}>Sign in to continue to your clinic.</div>
      </div>

      <div className="col" style={{gap: 8, marginTop: 24}}>
        <GoogleSignInButton onCredential={handleGoogle} onError={(m) => setError(m)}/>
      </div>

      <div className="ms-auth-divider"><span>or</span></div>

      <form className="ms-auth-password-form" onSubmit={handlePassword}>
        <div className="ms-auth-field">
          <label className="field-label">Work email</label>
          <input className="input input-lg" value={email} onChange={e => setEmail(e.target.value)} type="email" placeholder="you@clinic.com" autoComplete="email"/>
        </div>
        <div className="ms-auth-field">
          <div className="ms-auth-label-row">
            <label className="field-label">Password</label>
            <a href="#">Forgot?</a>
          </div>
          <div className="ms-auth-password-wrap">
            <input className="input input-lg" value={password} onChange={e => setPassword(e.target.value)} type={showPw ? "text" : "password"} placeholder="••••••••••••" autoComplete="current-password"/>
            <button type="button" onClick={() => setShowPw(s => !s)}>{showPw ? "Hide" : "Show"}</button>
          </div>
        </div>
        <label className="ms-check">
          <input type="checkbox" checked={remember} onChange={e => setRemember(e.target.checked)}/>
          <span>Keep me signed in on this device</span>
        </label>
        {error && (
          <div style={{padding: "10px 12px", borderRadius: 10, background: "color-mix(in oklch, var(--accent-danger) 10%, white)", border: "1px solid color-mix(in oklch, var(--accent-danger) 30%, white)", color: "var(--accent-danger)", fontSize: 12.5}}>{error}</div>
        )}
        <button type="submit" className="btn btn-primary btn-lg" disabled={pending} style={{width: "100%", justifyContent: "center", opacity: pending ? 0.7 : 1}}>
          {pending ? "Signing in…" : <>Sign in <Icon.ArrowRight size={16}/></>}
        </button>
      </form>

      <div className="ms-auth-switch">
        New to MedSync? <a onClick={onSwitch}>Create an account</a>
      </div>
    </AuthShell>
  );
}

function SignUp({ onDone, onSwitch }) {
  const [step, setStep] = useStateA(0);
  const [data, setData] = useStateA({ clinicSize: "small" });
  const [pending, setPending] = useStateA(false);
  const [error, setError] = useStateA("");
  const set = (k, v) => setData(d => ({...d, [k]: v}));

  const SIZES = [
    { id: "solo", label: "Solo", sub: "1 provider" },
    { id: "small", label: "Small group", sub: "2–10 providers" },
    { id: "mid", label: "Mid-size", sub: "11–50 providers" },
    { id: "large", label: "Large", sub: "50+ providers" },
  ];

  async function handleGoogle(credential) {
    setError("");
    setPending(true);
    try {
      const resp = await postAuth("/api/auth/google", { credential });
      applyAuthSuccess(resp);
      onDone(resp);
    } catch (e) {
      setError(e.message || "Google sign-up failed.");
    } finally {
      setPending(false);
    }
  }

  async function handleCreate() {
    if (pending) return;
    if (!data.first || !data.last || !data.email || !data.pw) {
      setStep(0);
      setError("Please fill in your name, email, and password.");
      return;
    }
    const missing = passwordRequirements(data.pw).filter(item => !item.ok);
    if (missing.length) {
      setStep(0);
      setError("Password needs: " + missing.map(item => item.label.toLowerCase()).join(", ") + ".");
      return;
    }
    setError("");
    setPending(true);
    try {
      const fullName = `${data.first} ${data.last}`.trim();
      const resp = await postAuth("/api/auth/register", {
        name: fullName,
        email: data.email,
        password: data.pw,
        specialty: data.specialty || null,
      });
      applyAuthSuccess(resp);
      onDone(resp);
    } catch (e) {
      setError(e.message || "Could not create your account.");
    } finally {
      setPending(false);
    }
  }

  return (
    <AuthShell
      side={
        <div className="ms-auth-pitch">
          <div className="eyebrow" style={{color: "rgba(255,255,255,0.7)"}}>Get started</div>
          <h1 className="h1" style={{color: "white", fontSize: 32, marginTop: 12, lineHeight: 1.2}}>Set up your clinic in under 5 minutes.</h1>
          <ul className="ms-auth-bullets">
            <li><Icon.Check size={16}/>30-day free trial — no card required</li>
            <li><Icon.Check size={16}/>Import patients & schedule from your current EHR</li>
            <li><Icon.Check size={16}/>HIPAA Business Associate Agreement included</li>
            <li><Icon.Check size={16}/>Dedicated onboarding specialist</li>
          </ul>
        </div>
      }
    >
      <div className="row" style={{gap: 6, marginBottom: 20}}>
        {[0, 1].map(i => (
          <div key={i} className="ms-step-pip" style={{background: i <= step ? "var(--primary)" : "var(--bg-sunk)"}}/>
        ))}
      </div>

      {step === 0 && (
        <div className="fade-in">
          <h1 className="h1" style={{fontSize: 24}}>Create your account</h1>
          <div style={{color: "var(--ink-3)", marginTop: 6, fontSize: 14}}>Start with the basics. We'll set up your clinic next.</div>

          <div className="col" style={{gap: 12, marginTop: 20}}>
            <GoogleSignInButton onCredential={handleGoogle} onError={(m) => setError(m)}/>
            <div className="ms-auth-divider" style={{margin: "8px 0"}}><span>or</span></div>
            <div className="ms-name-row">
              <div className="col" style={{flex: 1}}>
                <label className="field-label">First name</label>
                <input className="input input-lg" value={data.first || ""} onChange={e => set("first", e.target.value)}/>
              </div>
              <div className="col" style={{flex: 1}}>
                <label className="field-label">Last name</label>
                <input className="input input-lg" value={data.last || ""} onChange={e => set("last", e.target.value)}/>
              </div>
            </div>
            <div>
              <label className="field-label">Work email</label>
              <input className="input input-lg" type="email" placeholder="you@clinic.com" value={data.email || ""} onChange={e => set("email", e.target.value)}/>
            </div>
            <div>
              <label className="field-label">Create password</label>
              <input className="input input-lg" type="password" placeholder="8+ chars, uppercase, number, symbol" value={data.pw || ""} onChange={e => set("pw", e.target.value)}/>
              <PasswordStrength value={data.pw || ""}/>
            </div>
            {error && (
              <div style={{padding: "10px 12px", borderRadius: 10, background: "color-mix(in oklch, var(--accent-danger) 10%, white)", border: "1px solid color-mix(in oklch, var(--accent-danger) 30%, white)", color: "var(--accent-danger)", fontSize: 12.5}}>{error}</div>
            )}
            <button className="btn btn-primary btn-lg" onClick={() => setStep(1)} style={{width: "100%", justifyContent: "center", marginTop: 4}}>Continue <Icon.ArrowRight size={16}/></button>
          </div>
        </div>
      )}

      {step === 1 && (
        <div className="fade-in">
          <h1 className="h1" style={{fontSize: 24}}>Tell us about your clinic</h1>
          <div style={{color: "var(--ink-3)", marginTop: 6, fontSize: 14}}>We'll set up your workspace and invite your team.</div>

          <div className="col" style={{gap: 14, marginTop: 20}}>
            <div>
              <label className="field-label">Clinic name</label>
              <input className="input input-lg" placeholder="e.g. Bayview Family Health" value={data.clinicName || ""} onChange={e => set("clinicName", e.target.value)}/>
            </div>
            <div>
              <label className="field-label">Specialty</label>
              <select className="input input-lg" value={data.specialty || ""} onChange={e => set("specialty", e.target.value)}>
                <option value="">Select…</option>
                <option>Primary care / family medicine</option>
                <option>Internal medicine</option>
                <option>Dental practice</option>
                <option>Pediatrics</option>
                <option>Multi-specialty group</option>
                <option>Urgent care</option>
                <option>Mental / behavioral health</option>
                <option>Other</option>
              </select>
            </div>
            <div>
              <label className="field-label">Practice size</label>
              <div className="ms-size-grid">
                {SIZES.map(s => (
                  <button key={s.id} className={"ms-size" + (data.clinicSize === s.id ? " is-active" : "")} onClick={() => set("clinicSize", s.id)}>
                    <div style={{fontWeight: 600, fontSize: 13}}>{s.label}</div>
                    <div style={{fontSize: 11.5, color: "var(--ink-4)"}}>{s.sub}</div>
                  </button>
                ))}
              </div>
            </div>
            {error && (
              <div style={{padding: "10px 12px", borderRadius: 10, background: "color-mix(in oklch, var(--accent-danger) 10%, white)", border: "1px solid color-mix(in oklch, var(--accent-danger) 30%, white)", color: "var(--accent-danger)", fontSize: 12.5}}>{error}</div>
            )}
          </div>

          <div className="row" style={{gap: 8, marginTop: 20}}>
            <button className="btn btn-lg" onClick={() => setStep(0)} style={{flex: 1, justifyContent: "center"}}><Icon.ChevronLeft size={15}/>Back</button>
            <button className="btn btn-primary btn-lg" disabled={pending} onClick={handleCreate} style={{flex: 2, justifyContent: "center", opacity: pending ? 0.7 : 1}}>
              {pending ? "Creating…" : <>Create clinic <Icon.Check size={15}/></>}
            </button>
          </div>
          <div style={{fontSize: 11.5, color: "var(--ink-4)", marginTop: 12, textAlign: "center"}}>By creating an account, you agree to our Terms and HIPAA BAA.</div>
        </div>
      )}

      <div className="ms-auth-switch">
        Already have an account? <a onClick={onSwitch}>Sign in</a>
      </div>
    </AuthShell>
  );
}

function passwordRequirements(value) {
  const text = value || "";
  return [
    { key: "length", label: "8+ characters", ok: text.length >= 8 },
    { key: "upper", label: "uppercase letter", ok: /[A-Z]/.test(text) },
    { key: "lower", label: "lowercase letter", ok: /[a-z]/.test(text) },
    { key: "number", label: "number", ok: /\d/.test(text) },
    { key: "symbol", label: "special character", ok: /[^A-Za-z0-9]/.test(text) },
  ];
}

function PasswordStrength({ value }) {
  const requirements = passwordRequirements(value);
  const met = requirements.filter(item => item.ok).length;
  const score = value ? Math.min(4, met) : 0;
  const labels = ["Too short", "Weak", "Fair", "Good", "Strong"];
  const colors = ["var(--ink-5)", "var(--accent-danger)", "var(--accent-warn)", "var(--accent-success)", "var(--accent-success)"];
  return (
    <div style={{marginTop: 8}}>
      <div className="row" style={{gap: 4}}>
        {[0,1,2,3].map(i => (
          <div key={i} style={{flex: 1, height: 3, borderRadius: 999, background: i < score ? colors[score] : "var(--bg-sunk)"}}/>
        ))}
        <span style={{fontSize: 11, color: "var(--ink-4)", marginLeft: 6, minWidth: 60}}>{value ? labels[score] : ""}</span>
      </div>
      <div className="ms-password-rules">
        {requirements.map(item => (
          <span key={item.key} className={item.ok ? "is-met" : ""}>
            {item.ok ? <Icon.Check size={11}/> : <Icon.X size={11}/>}
            {item.label}
          </span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { SignIn, SignUp });
