/* composer.jsx — shared extras for every "chat with Yoshi" bar:
     · ComposerVoicePlus — the + (attach a document) and mic (voice) buttons.
       Renders its own AttachDocsSheet and VoiceOverlay; both are absolute
       inset-0, so they fill the host screen (mobile) or pillar (web).
     · AttachDocsSheet — pick a document to hand Yoshi as context.
     · VoiceOverlay — the spoken conversation: the chat steps aside and the
       Yoshi mark breathes while you talk. Tap anywhere to end.
   Used by: chat, proposal threads, brief details, approvals, automations,
   and the Studio rule composer. */

const ATTACH_DOCS = [
  { id: "1099b", name: "1099-B · 2025", sub: "Yoshi Securities · tax form", icon: "doc" },
  { id: "1099int", name: "1099-INT · 2025", sub: "Yoshi Cash · tax form", icon: "doc" },
  { id: "w2", name: "W-2 · 2025", sub: "Acme Corp · added Jan 28", icon: "doc" },
  { id: "chase-may", name: "Chase statement · May", sub: "External · checking ••4471", icon: "receipt" },
  { id: "paystub", name: "Pay stub · May 30", sub: "Acme Corp · direct deposit", icon: "receipt" },
];

const attachReplyFor = (doc) =>
  `Got it — I've read your ${doc.name}. Ask me anything about it, or tell me what you'd like done with it and I'll put together something you can approve.`;

/* the "subsequent page": pick a document to attach */
const AttachDocsSheet = ({ onClose, onAttach }) => (
  <div className="push-enter" data-screen-label="Attach a document" style={{ position: "absolute", inset: 0, zIndex: 700, background: "var(--bg)", display: "flex", flexDirection: "column" }}>
    <div style={{ flex: "none", padding: "14px 16px 10px", borderBottom: "1px solid var(--rule)", display: "flex", alignItems: "center", gap: 8, minHeight: 44 }}>
      <button className="press" onClick={onClose} aria-label="Back" style={{ background: "none", border: "none", display: "flex", color: "var(--ink)", padding: 6, margin: "0 -6px", cursor: "pointer" }}><Icon name="back" size={20} /></button>
      <span style={{ fontFamily: "var(--f-display)", fontSize: 17, fontWeight: 600, letterSpacing: "-0.02em", flex: 1 }}>Attach a document</span>
    </div>
    <div className="scroll" style={{ overflowY: "auto", padding: "0 0 24px" }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: 12.5, color: "var(--ink-2)", padding: "14px 20px 0", lineHeight: 1.5 }}>Yoshi reads what you attach and uses it as context — a tax form, a statement, a pay stub.</div>

      <button className="press" onClick={() => onAttach({ id: "upload", name: "Scanned document", sub: "Uploaded just now", icon: "doc" })}
        style={{ width: "calc(100% - 40px)", margin: "16px 20px 0", display: "flex", alignItems: "center", gap: 12, padding: "13px", background: "transparent", border: "1px dashed var(--rule-2)", borderRadius: 12, cursor: "pointer", textAlign: "left" }}>
        <span style={{ width: 32, height: 32, flex: "none", border: "1px dashed var(--rule-2)", borderRadius: 9, display: "grid", placeItems: "center", color: "var(--ink-2)" }}>
          <Icon name="download" size={16} stroke={1.5} style={{ transform: "rotate(180deg)" }} />
        </span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 600, color: "var(--ink)" }}>Upload from this device</div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>PDF, photo, or CSV</div>
        </div>
      </button>

      <div style={{ padding: "18px 20px 0" }}><Eyebrow>Your documents</Eyebrow></div>
      <div style={{ margin: "10px 20px 0", border: "1px solid var(--rule-2)", background: "var(--bg-card)", borderRadius: 12, overflow: "hidden" }}>
        {ATTACH_DOCS.map((d, i) => (
          <button key={d.id} className="press" onClick={() => onAttach(d)} style={{ width: "100%", textAlign: "left", display: "flex", alignItems: "center", gap: 12, padding: "13px 14px", background: "none", border: "none", borderTop: i ? "1px solid var(--rule)" : "none", cursor: "pointer" }}>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{d.name}</div>
              <div style={{ fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>{d.sub}</div>
            </div>
            <Icon name="plus" size={16} color="var(--ink-3)" style={{ flex: "none" }} />
          </button>
        ))}
      </div>

      <div style={{ display: "flex", gap: 9, alignItems: "flex-start", margin: "20px 20px 0", padding: "10px 12px", background: "var(--bg-2)" }}>
        <Icon name="shield" size={16} color="var(--ink-3)" stroke={1.5} style={{ marginTop: 1 }} />
        <span style={{ fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)", lineHeight: 1.45 }}>Documents stay in your account. Yoshi reads them to answer you; nothing is shared with the agent's provider.</span>
      </div>
    </div>
  </div>
);

/* the spoken conversation — chat steps aside, the mark breathes. Tap to end. */
const VoiceOverlay = ({ onClose }) => {
  const [stage, setStage] = useState(0);
  useEffect(() => { const id = setInterval(() => setStage((s) => (s + 1) % 2), 3600); return () => clearInterval(id); }, []);
  return (
    <div onClick={onClose} data-screen-label="Voice" style={{ position: "absolute", inset: 0, zIndex: 720, background: "var(--bg)", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", cursor: "pointer", animation: "fade-swap 200ms ease both" }}>
      <style>{`
        @keyframes yo-voice-morph { 0%, 100% { border-radius: 47% 53% 63% 37% / 52% 44% 56% 48%; } 25% { border-radius: 60% 40% 41% 59% / 58% 62% 38% 42%; } 50% { border-radius: 38% 62% 56% 44% / 44% 38% 62% 56%; } 75% { border-radius: 55% 45% 38% 62% / 40% 55% 45% 60%; } }
        @keyframes yo-voice-breathe { 0%, 100% { transform: scale(0.94); } 50% { transform: scale(1.06); } }
        @keyframes yo-voice-ring { from { transform: scale(0.72); opacity: 0.45; } to { transform: scale(1.85); opacity: 0; } }
      `}</style>
      <div style={{ position: "relative", width: 190, height: 190, display: "grid", placeItems: "center" }}>
        {[0, 1, 2].map((i) => (
          <span key={i} style={{ position: "absolute", inset: 22, borderRadius: 999, border: "1px solid var(--accent)", opacity: 0, animation: "yo-voice-ring 2.8s linear infinite", animationDelay: `${i * 0.93}s` }} />
        ))}
        <div style={{ width: 126, height: 126, display: "grid", placeItems: "center", background: "color-mix(in srgb, var(--accent) 13%, var(--bg-card))", border: "1px solid var(--accent)", animation: "yo-voice-morph 7s ease-in-out infinite, yo-voice-breathe 3.2s ease-in-out infinite" }}>
          <Logo size={52} />
        </div>
      </div>
      <div style={{ marginTop: 32, fontFamily: "var(--f-display)", fontSize: 16, fontWeight: 600, letterSpacing: "-0.01em" }}>{stage === 0 ? "Listening…" : "Yoshi is responding…"}</div>
      <div style={{ marginTop: 9, fontFamily: "var(--f-display)", fontSize: 12, color: "var(--ink-3)" }}>Tap anywhere to end the conversation</div>
    </div>
  );
};

/* the + and mic that live in every Yoshi composer */
const ComposerVoicePlus = ({ onAttach, size = 32 }) => {
  const [attachOpen, setAttachOpen] = useState(false);
  const [voiceOpen, setVoiceOpen] = useState(false);
  const btn = { width: size, height: size, flex: "none", borderRadius: 999, background: "none", border: "none", display: "grid", placeItems: "center", color: "var(--ink-2)", cursor: "pointer", padding: 0 };
  return (
    <>
      <button className="press" aria-label="Attach a document" title="Attach a document" onClick={() => setAttachOpen(true)} style={btn}>
        <Icon name="plus" size={19} stroke={1.6} />
      </button>
      <button className="press" aria-label="Talk to Yoshi" title="Talk to Yoshi" onClick={() => setVoiceOpen(true)} style={btn}>
        <Icon name="mic" size={18} stroke={1.6} />
      </button>
      {attachOpen && <AttachDocsSheet onClose={() => setAttachOpen(false)} onAttach={(d) => { setAttachOpen(false); onAttach && onAttach(d); }} />}
      {voiceOpen && <VoiceOverlay onClose={() => setVoiceOpen(false)} />}
    </>
  );
};

/* The Yoshi chat bar — one pill everywhere:
   [ + ] circle on the left (attach a document) · the input · a mic that
   dictates into the input (voice-to-text; the bar stays visible and the user
   still hits send) · and a circle on the right that idles as a waveform
   (full voice conversation) and becomes the send arrow once there's text. */
const DICTATION_SAMPLE = "Can you give me a quick update on my accounts?";
const YoshiComposer = ({ value, onChange, onSend, placeholder, onAttach, onThreadJump }) => {
  const [attachOpen, setAttachOpen] = useState(false);
  const [voiceOpen, setVoiceOpen] = useState(false);
  const [dictating, setDictating] = useState(false);
  const dictTimer = useRef(null);
  useEffect(() => () => clearInterval(dictTimer.current), []);
  const stopDictation = () => { clearInterval(dictTimer.current); setDictating(false); };
  const toggleDictation = () => {
    if (dictating) { stopDictation(); return; }
    setDictating(true);
    // voice-to-text: words land in the input as you speak; you still hit send
    const words = DICTATION_SAMPLE.split(" ");
    let i = 0;
    const base = value && value.trim() ? value.replace(/\s+$/, "") + " " : "";
    dictTimer.current = setInterval(() => {
      i += 1;
      onChange(base + words.slice(0, i).join(" "));
      if (i >= words.length) stopDictation();
    }, 160);
  };
  const has = !!(value && value.trim());
  const circ = (extra) => ({ width: 40, height: 40, flex: "none", borderRadius: 999, display: "grid", placeItems: "center", cursor: "pointer", border: "none", background: "color-mix(in srgb, var(--ink) 8%, var(--bg-2))", color: "var(--ink-2)", padding: 0, ...extra });
  const inline = { width: 32, height: 32, flex: "none", background: "none", border: "none", display: "grid", placeItems: "center", color: "var(--ink-2)", cursor: "pointer", padding: 0 };
  return (
    <>
      <style>{`@keyframes yo-dict-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }`}</style>
      <div style={{ display: "flex", alignItems: "center", gap: 8, padding: 5, background: "var(--bg-2)", border: "1px solid var(--rule-2)", borderRadius: 999 }}>
        {/* attach — visual affordance only; the backend decides what attaching does */}
        <button aria-label="Attach a document" title="Attach a document" style={circ({ cursor: "default" })}>
          <Icon name="plus" size={19} stroke={1.5} />
        </button>
        <input value={value} onChange={(e) => onChange(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") onSend(); }} placeholder={dictating ? "Listening…" : placeholder}
          style={{ flex: 1, minWidth: 0, padding: 0, background: "transparent", border: "none", color: "var(--ink)", fontFamily: "var(--f-display)", fontSize: 14, outline: "none" }} />
        {onThreadJump &&
        <button className="press" onClick={onThreadJump} aria-label="Open proposal thread" title="Open proposal thread" style={inline}>
          <Icon name="chat" size={17} stroke={1.6} />
        </button>}
        <button className="press" aria-label={dictating ? "Stop dictating" : "Talk to Yoshi"} title={dictating ? "Stop dictating" : "Talk to Yoshi"} onClick={toggleDictation}
          style={{ ...inline, marginRight: -6, color: dictating ? "var(--accent)" : "var(--ink-2)", animation: dictating ? "yo-dict-pulse 1.1s ease-in-out infinite" : "none" }}>
          <Icon name="mic" size={18} stroke={1.6} />
        </button>
        {has ? (
          <button className="press" onClick={() => onSend()} aria-label="Send" style={circ({ background: "var(--accent)", color: "var(--accent-ink)" })}>
            <Icon name="arrow" size={18} color="var(--accent-ink)" />
          </button>
        ) : (
          <button className="press" aria-label="Voice conversation" title="Voice conversation" onClick={() => setVoiceOpen(true)} style={{ ...inline, width: 40, height: 40 }}>
            <Icon name="waveform" size={19} stroke={1.6} />
          </button>
        )}
      </div>
      {attachOpen && false && <AttachDocsSheet onClose={() => setAttachOpen(false)} onAttach={(d) => { setAttachOpen(false); onAttach && onAttach(d); }} />}
      {voiceOpen && <VoiceOverlay onClose={() => setVoiceOpen(false)} />}
    </>
  );
};

Object.assign(window, { ComposerVoicePlus, AttachDocsSheet, VoiceOverlay, ATTACH_DOCS, attachReplyFor, YoshiComposer });
