import { useState, useEffect, useRef } from "react" import { Send, LogIn } from "lucide-react" import { authClient } from "@/lib/auth-client" type Comment = { id: string user_id: string user_name: string user_email: string content: string created_at: string } type AuthStep = "idle" | "email" | "otp" interface CommentBoxProps { username: string } export function CommentBox({ username }: CommentBoxProps) { const { data: session, isPending: sessionLoading } = authClient.useSession() const [comments, setComments] = useState([]) const [newComment, setNewComment] = useState("") const [isSubmitting, setIsSubmitting] = useState(false) const [isLoading, setIsLoading] = useState(true) // Auth state const [authStep, setAuthStep] = useState("idle") const [email, setEmail] = useState("") const [otp, setOtp] = useState("") const [authLoading, setAuthLoading] = useState(false) const [authError, setAuthError] = useState("") const commentsEndRef = useRef(null) const emailInputRef = useRef(null) const otpInputRef = useRef(null) // Focus inputs when auth step changes useEffect(() => { if (authStep === "email") { emailInputRef.current?.focus() } else if (authStep === "otp") { otpInputRef.current?.focus() } }, [authStep]) // Fetch comments useEffect(() => { const fetchComments = async () => { try { const res = await fetch(`/api/stream-comments?username=${username}`) if (res.ok) { const data = (await res.json()) as { comments?: Comment[] } setComments(data.comments || []) } } catch (err) { console.error("Failed to fetch comments:", err) } finally { setIsLoading(false) } } fetchComments() const interval = setInterval(fetchComments, 5000) // Poll every 5 seconds return () => clearInterval(interval) }, [username]) // Scroll to bottom when new comments arrive useEffect(() => { commentsEndRef.current?.scrollIntoView({ behavior: "smooth" }) }, [comments]) const handleSendOTP = async (e: React.FormEvent) => { e.preventDefault() if (!email.trim()) return setAuthLoading(true) setAuthError("") try { const result = await authClient.emailOtp.sendVerificationOtp({ email, type: "sign-in", }) if (result.error) { setAuthError(result.error.message || "Failed to send code") } else { setAuthStep("otp") } } catch (err) { setAuthError(err instanceof Error ? err.message : "Failed to send verification code") } finally { setAuthLoading(false) } } const handleVerifyOTP = async (e: React.FormEvent) => { e.preventDefault() if (!otp.trim()) return setAuthLoading(true) setAuthError("") try { const result = await authClient.signIn.emailOtp({ email, otp, }) if (result.error) { setAuthError(result.error.message || "Invalid code") } else { // Success - close auth form setAuthStep("idle") setEmail("") setOtp("") } } catch (err) { setAuthError(err instanceof Error ? err.message : "Failed to verify code") } finally { setAuthLoading(false) } } const handleSubmitComment = async (e: React.FormEvent) => { e.preventDefault() if (!newComment.trim() || !session?.user) return setIsSubmitting(true) try { const res = await fetch("/api/stream-comments", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, content: newComment.trim(), }), }) if (res.ok) { const data = (await res.json()) as { comment: Comment } setComments((prev) => [...prev, data.comment]) setNewComment("") } } catch (err) { console.error("Failed to post comment:", err) } finally { setIsSubmitting(false) } } const formatTime = (dateStr: string) => { const date = new Date(dateStr) return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) } const isAuthenticated = !!session?.user return (
{/* Header */}

Chat

{/* Comments list */}
{isLoading ? (
Loading...
) : comments.length === 0 ? (
No messages yet. Be the first to say hi!
) : ( comments.map((comment) => (
{comment.user_name?.charAt(0).toUpperCase() || "?"}
{comment.user_name || "Anonymous"} {formatTime(comment.created_at)}

{comment.content}

)) )}
{/* Input area */}
{sessionLoading ? (
Loading...
) : isAuthenticated ? (
setNewComment(e.target.value)} placeholder="Send a message..." className="flex-1 bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder:text-white/30 focus:outline-none focus:border-white/20" disabled={isSubmitting} />
) : authStep === "idle" ? ( ) : authStep === "email" ? (
setEmail(e.target.value)} className="w-full bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder:text-white/30 focus:outline-none focus:border-white/20" /> {authError && (

{authError}

)}
) : (

Code sent to {email}

setOtp(e.target.value.replace(/\D/g, ""))} className="w-full bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-center text-lg font-mono tracking-widest text-white placeholder:text-white/30 focus:outline-none focus:border-white/20" /> {authError && (

{authError}

)}
)}
) }