// KASHA website — 실시간 문의 채팅 위젯 (우하단 플로팅)
// 서버(/api/chat, D1)를 통해 관리자와 실시간으로 연결돼요. 상대가 입력 중이면
// '입력 중…' 모션이 표시됩니다. 백엔드가 없으면 자동으로 로컬(KASHADB)로 폴백.
function getGuestId() {
  try {
    var g = window.localStorage.getItem("kasha_guest_id");
    if (!g) { g = "G-" + Date.now(); window.localStorage.setItem("kasha_guest_id", g); }
    return g;
  } catch (e) { return "G-anon"; }
}

function TypingDots({ color }) {
  const dot = (d) => ({ width: 6, height: 6, borderRadius: 999, background: color || "var(--gray-500)", display: "inline-block", animation: "kashaTypeBlink 1.2s infinite", animationDelay: d });
  return (
    <span style={{ display: "inline-flex", gap: 4, alignItems: "center" }}>
      <span style={dot("0s")} /><span style={dot("0.2s")} /><span style={dot("0.4s")} />
    </span>
  );
}

function ChatWidget() {
  const { Icon } = window.DS;
  const user = window.KASHADB.getCurrentUser();
  const userId = user ? user.id : getGuestId();
  const userName = user ? user.name : "방문자";

  const T = window.KASHAChat.useThread(userId, "user", userName);
  const messages = T.messages;
  const unread = T.unread;

  const [open, setOpen] = React.useState(false);
  const [text, setText] = React.useState("");
  const bottomRef = React.useRef(null);
  const imgRef = React.useRef(null);

  React.useEffect(() => {
    if (open) {
      T.markRead();
      if (bottomRef.current) bottomRef.current.scrollIntoView({ behavior: "smooth" });
    }
  }, [open, messages.length, T.typingOther]);

  const lastMineIdx = messages.reduce((a, m, i) => (m.from === "user" ? i : a), -1);

  const send = () => {
    if (!text.trim()) return;
    T.send(text.trim());
    setText("");
  };
  const onChange = (e) => { setText(e.target.value); T.notifyTyping(); };
  const onPickImage = async (e) => {
    const f = e.target.files && e.target.files[0]; if (!f) return;
    try { const src = await window.KASHAUpload.upload(f, 1000, 0.5); T.send("", src); } catch (err) {}
    e.target.value = "";
  };
  const onKey = (e) => {
    if (e.isComposing || e.nativeEvent.isComposing || e.keyCode === 229) return;
    if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(); }
  };

  return (
    <div style={{ position: "fixed", right: 24, bottom: 24, zIndex: 1500, fontFamily: "var(--font-sans)" }}>
      <div style={{
        position: "absolute", right: 0, bottom: 72, width: 340, maxWidth: "calc(100vw - 48px)",
        background: "#fff", borderRadius: "var(--radius-lg)", boxShadow: "var(--shadow-xl)", overflow: "hidden",
        transformOrigin: "bottom right",
        transform: open ? "translateY(0) scale(1)" : "translateY(12px) scale(0.96)",
        opacity: open ? 1 : 0, pointerEvents: open ? "auto" : "none",
        transition: "transform var(--dur-base) var(--ease-ios), opacity var(--dur-base) var(--ease-ios)",
      }}>
        <div style={{ background: "var(--ink)", color: "#fff", padding: "16px 18px", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontSize: 15, fontWeight: 700 }}>KASHA 문의</div>
            <div style={{ fontSize: 12, color: "var(--gray-400)", marginTop: 2, height: 16 }}>
              {T.typingOther ? <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>입력 중<TypingDots color="var(--gray-300)" /></span> : "보통 몇 분 안에 답변드려요"}
            </div>
          </div>
          <button onClick={() => setOpen(false)} aria-label="닫기" style={{ border: "none", background: "rgba(255,255,255,0.15)", width: 30, height: 30, borderRadius: 8, color: "#fff", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
            <Icon name="x" size={18} color="#fff" />
          </button>
        </div>

        <div style={{ height: 320, overflowY: "auto", padding: "16px 16px 8px", background: "var(--gray-50)" }}>
          {messages.length === 0 && (
            <div style={{ textAlign: "center", color: "var(--text-tertiary)", fontSize: 13, marginTop: 28, lineHeight: 1.6 }}>
              궁금한 점을 남겨 주세요.<br />KASHA가 직접 답변드려요.
            </div>
          )}
          {messages.map((m, i) => {
            const mine = m.from === "user";
            return (
              <div key={i} style={{ display: "flex", flexDirection: "column", alignItems: mine ? "flex-end" : "flex-start", marginBottom: 8 }}>
                <div style={{
                  maxWidth: "78%", padding: m.image ? 4 : "10px 13px", borderRadius: 14, fontSize: 13.5, lineHeight: 1.45,
                  background: mine ? "var(--blue-500)" : "#fff",
                  color: mine ? "#fff" : "var(--text-strong)",
                  border: mine ? "none" : "1px solid var(--border-subtle)",
                  borderBottomRightRadius: mine ? 4 : 14, borderBottomLeftRadius: mine ? 14 : 4,
                }}>
                  {m.image ? <img src={m.image} alt="" style={{ maxWidth: 180, borderRadius: 10, display: "block" }} /> : m.text}
                </div>
                {mine && T.mineRead && i === lastMineIdx && <span style={{ fontSize: 10, color: "var(--text-tertiary)", marginTop: 3 }}>읽음</span>}
              </div>
            );
          })}
          {T.typingOther && (
            <div style={{ display: "flex", justifyContent: "flex-start", marginBottom: 8 }}>
              <div style={{ padding: "12px 14px", borderRadius: 14, borderBottomLeftRadius: 4, background: "#fff", border: "1px solid var(--border-subtle)" }}>
                <TypingDots />
              </div>
            </div>
          )}
          <div ref={bottomRef} />
        </div>

        <div style={{ display: "flex", gap: 8, padding: "12px", borderTop: "1px solid var(--border-subtle)", alignItems: "center" }}>
          <input ref={imgRef} type="file" accept="image/*" style={{ display: "none" }} onChange={onPickImage} />
          <button onClick={() => imgRef.current && imgRef.current.click()} aria-label="사진 첨부" style={{ width: 42, height: 42, borderRadius: 12, border: "1.5px solid var(--border-default)", background: "#fff", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
            <Icon name="image" size={20} color="var(--gray-600)" />
          </button>
          <input value={text} onChange={onChange} onKeyDown={onKey} placeholder="메시지를 입력하세요"
            style={{ flex: 1, height: 42, borderRadius: 12, border: "1.5px solid var(--border-default)", padding: "0 14px", fontFamily: "var(--font-sans)", fontSize: 14, outline: "none", minWidth: 0 }} />
          <button onClick={send} aria-label="전송" style={{ width: 42, height: 42, borderRadius: 12, border: "none", background: "var(--ink)", color: "#fff", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
            <Icon name="arrowRight" size={20} color="#fff" />
          </button>
        </div>
      </div>

      <button onClick={() => setOpen((o) => !o)} aria-label="문의 채팅"
        style={{ position: "relative", width: 56, height: 56, borderRadius: "50%", border: "none", background: "var(--ink)", color: "#fff", boxShadow: "var(--shadow-lg)", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
        <Icon name={open ? "x" : "phone"} size={24} color="#fff" />
        {!open && unread > 0 && (
          <span style={{ position: "absolute", top: -2, right: -2, minWidth: 20, height: 20, padding: "0 5px", borderRadius: 999, background: "var(--red-500)", color: "#fff", fontSize: 11, fontWeight: 700, display: "flex", alignItems: "center", justifyContent: "center", border: "2px solid #fff" }}>{unread}</span>
        )}
      </button>
    </div>
  );
}
window.ChatWidget = ChatWidget;
