/* global React */
function LeasingChat({ hidden }) {
  const [open, setOpen] = React.useState(false);
  const [history, setHistory] = React.useState([]);
  const [draft, setDraft] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const [ready, setReady] = React.useState(false);
  const [error, setError] = React.useState("");
  const [pending, setPending] = React.useState(null);
  const scope = React.useRef(null);
  const input = React.useRef(null);
  const log = React.useRef(null);
  const launcher = React.useRef(null);
  const flight = React.useRef(false);
  const timer = React.useRef(null);
  const savePending = (value) => {
    setPending(value);
    try { value ? sessionStorage.setItem("bwh-chat-pending", JSON.stringify(value)) : sessionStorage.removeItem("bwh-chat-pending"); } catch {}
  };
  const initialize = async () => {
    setError("");
    try {
      const response = await fetch("/api/chat/messages", { credentials: "same-origin", cache: "no-store", signal: AbortSignal.timeout(15000) });
      const result = await response.json();
      if (!response.ok || !result.ok) throw Error();
      scope.current = result.sessionScope;
      setHistory(result.history || []);
      let saved;
      try { saved = JSON.parse(sessionStorage.getItem("bwh-chat-pending") || "null"); } catch {}
      if (saved) {
        if (saved.scope !== result.sessionScope) {
          setDraft(saved.body.message || "");
          savePending(null);
          setError("Your earlier session expired. Your draft is below; sending it starts a new conversation.");
        } else { savePending(saved); setDraft(saved.body.message); setError("Your last response wasn't confirmed. Retry to retrieve it without sending a duplicate."); }
      }
      setReady(true);
    } catch { setError("Chat could not connect. Try reconnecting, or call (609) 710-7977."); }
  };
  React.useEffect(() => {
    if (open && !ready) initialize();
    if (open) input.current?.focus();
  }, [open]);
  React.useEffect(() => () => clearTimeout(timer.current), []);
  React.useEffect(() => { if (log.current) log.current.scrollTop = log.current.scrollHeight; }, [history]);
  const close = () => { setOpen(false); setTimeout(() => launcher.current?.focus(), 0); };
  const send = async (submission, poll = 0) => {
    if (flight.current) return;
    clearTimeout(timer.current);
    flight.current = true; setBusy(true); setError("");
    try {
      const response = await fetch("/api/chat/messages", { method: "POST", credentials: "same-origin", headers: { "Content-Type": "application/json" }, body: JSON.stringify(submission.body), signal: AbortSignal.timeout(35000) });
      const result = await response.json();
      if (!response.ok || !result.ok) throw Error(result.error || "Response unavailable");
      if (result.pending) {
        if (poll < 65) timer.current = setTimeout(() => send(submission, poll + 1), 2000);
        else setError("Your message is saved, but the response is taking longer. Retry to check again, or call us.");
        return;
      }
      if (typeof result.reply !== "string") throw Error();
      setHistory(current => {
        const rows = current.slice();
        if (rows.at(-1)?.role === "assistant" && rows.at(-1)?.content === result.reply && rows.at(-2)?.role === "user" && rows.at(-2)?.content === submission.body.message) return rows;
        if (!(rows.at(-1)?.role === "user" && rows.at(-1)?.content === submission.body.message)) rows.push({ role: "user", content: submission.body.message });
        rows.push({ role: "assistant", content: result.reply });
        return rows.slice(-24);
      });
      try {
        const refreshed = await fetch("/api/chat/messages", { credentials: "same-origin", cache: "no-store", signal: AbortSignal.timeout(10000) });
        const data = await refreshed.json();
        if (refreshed.ok && data.ok) setHistory(data.history || []);
      } catch {}
      savePending(null); setDraft("");
    } catch { setError("The response wasn't confirmed. Your message is preserved. Retry to check it without sending a duplicate, or call (609) 710-7977."); }
    finally { flight.current = false; setBusy(false); }
  };
  const submit = (event) => {
    event.preventDefault();
    if (!ready || busy || !draft.trim()) return;
    const submission = pending || { scope: scope.current, body: { requestId: crypto.randomUUID(), message: draft.trim(), ...(email.trim() ? { email: email.trim() } : {}), source: "website-chat", formType: "chat" } };
    savePending(submission);
    send(submission);
  };
  if (hidden) return null;
  return <div className="leasing-chat">
    {!open && <button ref={launcher} className="btn btn-primary chat-launcher" onClick={() => setOpen(true)} aria-expanded="false" aria-controls="leasing-chat-panel">Ask about apartments</button>}
    {open && <section id="leasing-chat-panel" className="chat-panel" aria-label="Apartment questions" onKeyDown={event => { if (event.key === "Escape") close(); }}>
      <div className="chat-heading"><div><strong>Boardwalk House</strong><span>AI leasing assistant</span></div><button type="button" onClick={close} aria-label="Close chat">×</button></div>
      <p className="chat-posture">Waitlist open. Appointments and lease signing are not open yet. Occupancy depends on the certificate of occupancy.</p>
      <div ref={log} className="chat-history" role="log" aria-label="Conversation" aria-live="polite">
        {!history.length && <p>Ask about layouts, estimated rent, or the waitlist. Please don’t share financial documents or sensitive personal information.</p>}
        {history.map((item, index) => <p key={index} className={item.role === "user" ? "chat-user" : "chat-assistant"}><b>{item.role === "user" ? "You" : "Assistant"}</b>{item.content}</p>)}
      </div>
      <form onSubmit={submit}>
        <label htmlFor="chat-email">Email for staff follow-up (optional)</label>
        <input id="chat-email" type="email" autoComplete="email" value={email} onChange={event => setEmail(event.target.value)} disabled={!!pending} />
        <label htmlFor="chat-message">Your message</label>
        <textarea ref={input} id="chat-message" maxLength={4000} rows={3} value={draft} onChange={event => setDraft(event.target.value)} disabled={!!pending} required />
        {error && <p className="chat-error" role="alert">{error}</p>}
        <p className="chat-status" role="status">{busy ? "Checking your response…" : pending && !error ? "Your message is saved. Waiting for the response…" : ""}</p>
        {ready ? <button className="btn btn-primary" disabled={busy || !draft.trim()} type="submit">{pending ? "Check response / retry" : "Send message"}</button> : <button type="button" className="btn btn-primary" onClick={initialize}>Reconnect chat</button>}
        <a href="tel:6097107977">Call (609) 710-7977</a>
        <small>Conversations are saved for leasing support. <a href="privacy.html" target="_blank" rel="noopener">Privacy policy</a></small>
      </form>
    </section>}
  </div>;
}
