import { useEffect, useState, useRef, forwardRef, useImperativeHandle } from "react"
import { useNavigate, useLocation } from "react-router-dom"
import {
MessageSquare, Plus, LayoutDashboard, CalendarClock, CheckSquare,
Trophy, User, LogOut, Trash2, MoreVertical, HelpCircle, BookOpen, Menu, X,
} from "lucide-react"
import { getConversations, createConversation } from "../api"
import { useAuth } from "../auth/AuthContext"
import { useI18n } from "../i18n/I18nContext"
import { useIsMobile } from "../useMediaQuery"
import HelpGuide from "./HelpGuide"
import { T } from "../theme"
const Sidebar = forwardRef(function Sidebar(
{ activeConversationId, onSelectConversation, onNewConversation, onDeleteConversation },
ref
) {
const [conversations, setConversations] = useState([])
const [menu, setMenu] = useState(null)
const [showHelp, setShowHelp] = useState(false)
const [drawerOpen, setDrawerOpen] = useState(false)
const navigate = useNavigate()
const location = useLocation()
const isMobile = useIsMobile()
const { logout, user } = useAuth()
const { t } = useI18n()
const topNav = [
{ icon: LayoutDashboard, label: t("nav_dashboard"), path: "/dashboard" },
{ icon: MessageSquare, label: t("nav_chat"), path: "/chat" },
{ icon: CalendarClock, label: t("nav_schedule"), path: "/schedule" },
{ icon: CheckSquare, label: t("nav_today"), path: "/today" },
{ icon: BookOpen, label: t("nav_medicines"), path: "/medicines" },
{ icon: Trophy, label: t("nav_leaderboard"), path: "/leaderboard" },
{ icon: User, label: t("nav_profile"), path: "/profile" },
]
useImperativeHandle(ref, () => ({
refresh: loadConversations,
updateTitle: (id, title) =>
setConversations((prev) => prev.map((c) => (c.id === id ? { ...c, title } : c))),
}))
useEffect(() => { loadConversations() }, [])
useEffect(() => { loadConversations() }, [activeConversationId])
useEffect(() => { setDrawerOpen(false) }, [location.pathname]) // close on navigation
useEffect(() => {
const close = () => setMenu(null)
document.addEventListener("click", close)
return () => document.removeEventListener("click", close)
}, [])
const loadConversations = async () => {
try { setConversations(await getConversations()) } catch (e) { console.error(e) }
}
const go = (path) => { navigate(path); setDrawerOpen(false) }
const handleNew = async () => {
if (onNewConversation) {
const id = await createConversation()
await loadConversations()
onNewConversation(id)
} else {
navigate("/chat")
}
setDrawerOpen(false)
}
const handleSelect = (id) => {
if (onSelectConversation) onSelectConversation(id)
else navigate("/chat")
setDrawerOpen(false)
}
const openMenu = (e, convId) => {
e.stopPropagation()
const r = e.currentTarget.getBoundingClientRect()
setMenu({ x: Math.min(r.left, window.innerWidth - 170), y: r.bottom + 4, convId })
}
const handleDelete = async () => {
if (!menu) return
if (onDeleteConversation) await onDeleteConversation(menu.convId)
await loadConversations()
setMenu(null)
}
const panel = (
<>
💊
DoseMate
{t("portal_subtitle")}
{topNav.map(({ icon: Icon, label, path }) => {
const active = location.pathname === path
return (
go(path)} style={navItem(active)}>
{label}
)
})}
RECENT CHATS
{conversations.map((conv) => {
const active = activeConversationId === conv.id
return (
handleSelect(conv.id)} style={chatRow(active)}>
{conv.title || `Consultation #${conv.number ?? conv.id}`}
)
})}
{ setShowHelp(true); setDrawerOpen(false) }} style={navItem(false)}>
{t("help")}
{(user?.name || "U").charAt(0).toUpperCase()}
{user?.name || "User"}
{user?.email}
>
)
const menuEl = menu && (
(e.currentTarget.style.background = "#fef2f2")}
onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}>
Delete chat
)
// ---------- Mobile: top bar + slide-in drawer ----------
if (isMobile) {
return (
<>
💊
DoseMate
{drawerOpen && setDrawerOpen(false)} />}
{panel}
{menuEl}
{showHelp &&
setShowHelp(false)} />}
>
)
}
// ---------- Desktop: fixed in-flow sidebar ----------
return (
{panel}
{menuEl}
{showHelp && setShowHelp(false)} />}
)
})
const wrap = { width: 240, height: "100%", background: T.surface, borderInlineEnd: `1px solid ${T.border}`, display: "flex", flexDirection: "column", padding: "20px 14px", flexShrink: 0, gap: 16 }
const drawer = { position: "fixed", insetInlineStart: 0, top: 0, height: "100%", width: 270, maxWidth: "82vw", background: T.surface, display: "flex", flexDirection: "column", padding: "18px 14px", gap: 14, zIndex: 1600, boxShadow: T.shadowLg, transition: "transform .25s ease", overflowY: "auto" }
const drawerClose = { position: "absolute", insetInlineEnd: 10, top: 10, background: "transparent", border: "none", color: T.faint, cursor: "pointer", padding: 4 }
const backdrop = { position: "fixed", inset: 0, background: "rgba(15,23,42,.45)", zIndex: 1550 }
const topbar = { position: "fixed", top: 0, insetInlineStart: 0, right: 0, height: 52, background: T.surface, borderBottom: `1px solid ${T.border}`, display: "flex", alignItems: "center", justifyContent: "space-between", padding: "0 12px", zIndex: 1400 }
const hamburger = { width: 38, height: 38, borderRadius: 10, background: "#f0fdf4", border: "1px solid #bbf7d0", color: T.green, display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer" }
const logo = { width: 38, height: 38, borderRadius: 12, background: T.gradient, display: "flex", alignItems: "center", justifyContent: "center", fontSize: 19, boxShadow: T.shadowGreen }
const newBtn = { display: "flex", alignItems: "center", justifyContent: "center", gap: 7, padding: "11px", borderRadius: 12, background: T.gradient, color: "#fff", border: "none", fontSize: 13.5, fontWeight: 600, cursor: "pointer", boxShadow: T.shadowGreen }
const navItem = (active) => ({ display: "flex", alignItems: "center", gap: 11, padding: "10px 12px", borderRadius: 11, cursor: "pointer", fontSize: 13.5, fontWeight: active ? 700 : 500, background: active ? "#f0fdf4" : "transparent", color: active ? T.green : T.muted })
const sectionLabel = { fontSize: 9.5, fontWeight: 700, color: T.faint, letterSpacing: ".09em", marginBottom: 8, paddingInlineStart: 4 }
const chatRow = (active) => ({ display: "flex", alignItems: "center", gap: 8, padding: "8px 8px 8px 12px", borderRadius: 9, cursor: "pointer", fontSize: 12.5, userSelect: "none", background: active ? "#f0fdf4" : "transparent", color: active ? T.green : T.muted, fontWeight: active ? 600 : 400 })
const dotsBtn = { background: "transparent", border: "none", color: T.faint, cursor: "pointer", padding: 2, borderRadius: 6, flexShrink: 0, display: "flex" }
const userRow = { display: "flex", alignItems: "center", gap: 9, padding: "9px 8px", marginTop: 2 }
const avatar = { width: 32, height: 32, borderRadius: "50%", background: T.gradient, color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 14, fontWeight: 700, flexShrink: 0 }
const logoutBtn = { background: "transparent", border: "none", color: T.faint, cursor: "pointer", padding: 6, borderRadius: 8, display: "flex" }
const menuBox = { background: "#fff", border: `1px solid ${T.border}`, borderRadius: 10, boxShadow: T.shadowMd, zIndex: 1700, overflow: "hidden", minWidth: 150 }
const menuItem = { display: "flex", alignItems: "center", gap: 8, padding: "10px 14px", cursor: "pointer", color: T.danger, fontSize: 13, fontWeight: 600 }
export default Sidebar