در صفحه ChatbotPage یک refactor فنی، ساختاری و production-grade انجام بده، اما به هیچ عنوان ساختار APIها، نام سرویس‌ها، endpointها، request/response contract، نام فیلدهای backend، و شکل داده‌های دریافتی/ارسالی را تغییر نده.
همه تغییرات فقط باید در لایه frontend انجام شوند: architecture، state management، rendering structure، async flow handling، message mapping، typing flow، UI composition و component extraction.

محدودیت بسیار مهم

ساختار APIها نباید تغییر کند.
یعنی:

sendChatMessage(...) باید حفظ شود
startMission(...) باید حفظ شود
مدل‌های ChatMessage و DoingMission تغییر نکنند
فیلدهایی مثل workflow_ID, question, answer, actions, is_mission_end, datetime1 دست‌نخورده بمانند
شکل responseها و نحوه ارتباط با backend تغییر نکند
فقط frontend refactor شود
هدف

صفحه ChatbotPage باید:

پایدارتر
دقیق‌تر
قابل نگهداری‌تر
بدون race condition
بدون memory leak
بدون تکرار منطق
و هماهنگ با ساختار صفحه Feed

باشد.

همچنین Header این صفحه باید از همان component هدر صفحه Feed استفاده کند و نباید header جدا و تکراری داخل ChatbotPage باقی بماند.

الزامات اصلی
1) از Header صفحه Feed استفاده کن

Header فعلی ChatbotPage را با ساختار مشترک و reusable جایگزین کن و از همان Header استفاده‌شده در FeedPage بهره ببر.

الزامات:

هدر duplicated داخل ChatbotPage حذف شود
یک component مشترک مثل FeedHeader یا معادل آن ساخته/استفاده شود
ظاهر هدر فعلی حفظ شود
back button behavior همچنان قابل کنترل باشد
لوگو، سکه، و ساختار visual فعلی حفظ شود
ChatbotPage فقط props لازم برای header را پاس بدهد

اگر لازم شد، هدر Feed را reusable کن، اما طراحی ظاهری را خراب نکن

2) ChatbotPage را از حالت چندمسئولیتی خارج کن

الان کامپوننت ChatbotPage هم‌زمان این مسئولیت‌ها را دارد:

route parsing
location state parsing
localStorage restore
mission bootstrap
chat mapping
date grouping
auto send start message
typing animation
message sending
multi-choice action handling
navigation logic
full page rendering

این ساختار را بشکن و مسئولیت‌ها را جدا کن.

ساختار پیشنهادی:

ChatbotPage → orchestration only
useMissionSession
useChatFlow
useTypingMessage
chat mappers
ChatMessageList
ChatInputBar
ChatTypingIndicator
ChatDateGroup
ChatBackground
3) منطق mission restore را از صفحه جدا کن

منطق مربوط به این بخش‌ها باید از خود page خارج شود:

خواندن location.state
خواندن searchParams
بررسی missionId, missionType, continueMode
sync کردن localStorage
restore mission با startMission(...)

این‌ها را داخل یک hook مثل این مدیریت کن:

useMissionSession(...)
یا معادل آن

این hook باید مسئول این موارد باشد:

resolve کردن mission source
restore از URL یا localStorage
اجرای startMission(...)
برگرداندن stateData
مدیریت loading/error state
جلوگیری از state update after unmount
4) برای تمام async flowها cleanup و guard اضافه کن

در نسخه فعلی setTimeout و setInterval بدون cleanup استفاده شده‌اند و requestها هم بدون guard اجرا می‌شوند.

این‌ها را اصلاح کن:

تمام timerها باید cleanup داشته باشند
setTimeout مربوط به auto-send باید cancel شود
setInterval مربوط به typing animation باید قبل از شروع مجدد clear شود
هنگام unmount شدن component هیچ state update نباید ادامه پیدا کند
response requestهای قدیمی نباید state جدید را overwrite کنند

از یکی از این الگوها استفاده کن:

ref-based cancellation
request id guard
mounted flag
abort/cancel pattern اگر سازگار است
5) typing animation را به hook جدا منتقل کن

منطق typeMessage(...) نباید داخل page بماند.

یک hook اختصاصی مثل این بساز:

useTypingMessage()

این hook باید:

isTyping
typingText
start typing
stop typing
cleanup interval
جلوگیری از overlap typing sessions

را مدیریت کند.

الزامات:

اگر typing جدید شروع شد، typing قبلی به‌درستی متوقف شود
اگر component unmount شد، intervalها پاک شوند
typing state به‌صورت deterministic مدیریت شود
6) منطق ارسال پیام را unify کن

در نسخه فعلی، flow ارسال پیام در چند جا تکرار شده:

auto-send "شروع"
ارسال پیام دستی با input
ارسال پاسخ دکمه‌های multi-choice

این تکرار باید حذف شود.

یک تابع یا hook مشترک بساز، مثلاً:

sendMissionMessage(messageText, options?)
یا در useChatFlow

این منطق مشترک باید این مراحل را یکجا انجام دهد:

validate پیام
append پیام کاربر در صورت نیاز
مدیریت pending state
اجرای sendChatMessage(...)
parse response
ساخت bot message
ساخت buttons از روی actions
مدیریت is_mission_end
نمایش خطا
اجرای typing animation
append final bot message

هیچ duplication بین handleSendMessage و handleButtonClick و auto-start باقی نماند.

7) request overlap را کنترل کن

در وضعیت فعلی، کاربر ممکن است:

چند بار سریع روی send بزند
چند بار روی button action کلیک کند
هم‌زمان چند درخواست chat بفرستد

این وضعیت باید کنترل شود.

الزامات:

هنگام ارسال request، state مناسب مثل isSending یا equivalent وجود داشته باشد
تا پایان request از ارسال موازی ناخواسته جلوگیری شود
buttonها در صورت نیاز disable شوند
input در حالت pending قابل کنترل باشد
responseها out-of-order باعث خراب شدن history نشوند
8) auto-send پیام "شروع" را پایدار و mission-aware کن

منطق auto-send فعلی باید دقیق‌تر شود.

الزامات:

فقط یک‌بار برای هر mission/workflow اجرا شود
اگر mission جدید load شد، flag مربوطه reset شود
اگر component unmount شد، timer اجرا نشود
اگر request fail شد، state ناسالم باقی نماند
append شدن پاسخ "شروع" با mission فعلی sync باشد
request mission قبلی نتواند پیام را به mission جدید اضافه کند
9) mapping داده‌های chat را از صفحه جدا کن

منطق تبدیل ChatMessage[] به Message[] را از خود ChatbotPage خارج کن.

یک mapper جدا بساز، مثلاً:

mapApiChatsToUiMessages(...)

این mapper باید:

سوال "شروع" را در صورت نیاز فیلتر کند
answerها را نگه دارد
datetime1 را منتقل کند
آخرین پیام مناسب برای attach کردن buttons را درست تشخیص دهد
contract API را تغییر ندهد
داده را صرفاً برای UI normalize کند
10) attach کردن action buttons را دقیق‌تر کن

در نسخه فعلی buttons فقط به آخرین index attach می‌شوند، نه لزوماً آخرین bot message واقعی.
این منطق را اصلاح کن.

الزامات:

buttons باید به آخرین پیام بات معتبر attach شوند
اگر آخرین آیتم کاربر بود، همچنان آخرین bot message درست پیدا شود
اگر is_mission_end = true بود، دکمه submit نیز به همان پیام درست attach شود
ساخت buttonها deterministic باشد
11) stateهای redundant را حذف یا درست استفاده کن

الان stateهایی مثل این‌ها نیاز به بازنگری دارند:

isMissionEnd
isLoadingMission

اگر این stateها در UI استفاده نمی‌شوند یا از پیام‌ها قابل استنتاج هستند:

حذف شوند
یا درست در UI مصرف شوند

state فقط وقتی نگه داشته شود که واقعاً لازم باشد.

12) date grouping را memoize و robust کن

تابع group کردن پیام‌ها بر اساس تاریخ را از render path خام خارج کن و memoize کن.

الزامات:

grouping فقط وقتی messages تغییر کرد دوباره محاسبه شود
اگر datetime1 خالی یا فرمتش ناقص بود، fallback امن وجود داشته باشد
تاریخ خالی یا invalid باعث header خراب نشود
parsing فقط به " - " fragile وابسته نباشد مگر fallback داشته باشد
13) scroll behavior را بهینه و کنترل‌شده کن

در نسخه فعلی با هر تغییر typingText اسکرول انجام می‌شود. این رفتار باید دقیق‌تر شود.

الزامات:

scroll به پایین فقط در نقاط لازم انجام شود
در زمان typing پیوسته jitter ایجاد نشود
اگر لازم بود فقط وقتی کاربر نزدیک پایین است auto-scroll انجام شود
روی موبایل نرم و پایدار باشد
14) مدل UI پیام‌ها را تمیز کن

مدل Message فعلی مبهم است، چون content گاهی متن است، گاهی image URL، گاهی video thumbnail.

بدون تغییر API، مدل داخلی UI را شفاف‌تر کن:

برای text content
برای image source
برای audio URL
برای video thumbnail/video URL
برای file metadata

اگر لازم شد یک UI view model داخلی بساز، اما API contract را تغییر نده

15) rendering media را یکدست و type-safe کن

رندر media باید دقیق‌تر و تمیزتر شود.

الزامات:

image از فیلد مناسب استفاده کند
video بین thumbnail و media url تفکیک واضح داشته باشد
audio URL درست بگیرد
file fake metadata مثل "PDF • 2.4 MB" را hardcode نکند مگر داده واقعی داشته باشد
اگر media ناقص بود، UI break نشود
16) منطق navigation را از UI جدا کن

این بخش نباید hardcoded داخل دکمه back باقی بماند:

اگر topicId === "3" → /feed/3
وگرنه navigate(-1)

این rule را به helper/domain logic منتقل کن:

getChatbotBackTarget(...)
یا معادل آن

ChatbotPage نباید business rule مسیر برگشت را مستقیم داخل JSX نگه دارد.

17) decorative background را پایدار کن

مانند FeedPage، ستاره‌ها نباید در هر render دوباره با Math.random() ساخته شوند.

الزامات:

داده ستاره‌ها فقط یک‌بار تولید شود
با useMemo یا state اولیه پایدار شود
هر rerender باعث visual jump نشود
ترجیحاً این بخش به ChatBackground یا component مشابه منتقل شود
18) performance rendering را بهتر کن

بهینه‌سازی‌های زیر را اعمال کن:

messageGroups memoized شود
handlerها در صورت نیاز stable شوند
از rerender غیرضروری جلوگیری شود
animation delay برای لیست‌های طولانی کنترل‌شده باشد
componentهای سنگین از page جدا شوند
19) textarea behavior را بهتر کن

Input area باید رفتاری production-ready داشته باشد.

الزامات:

به‌جای onKeyPress از event مناسب مثل onKeyDown استفاده شود
ارسال پیام با Enter و خط جدید با Shift+Enter حفظ شود
textarea در صورت نیاز auto-resize واقعی داشته باشد
در حالت sending/typing، رفتار input کنترل‌شده باشد
disable state شفاف باشد
20) loading و error state ماموریت را در UI منعکس کن

در حال حاضر restore mission ممکن است در حال loading باشد یا fail شود ولی UI آن را نشان نمی‌دهد.

اصلاح کن:

اگر mission در حال restore است، UI مناسب نمایش داده شود
اگر restore fail شد، کاربر در وضعیت مبهم نماند
صفحه نباید silently fail کند
21) styleها و selectorها را تمیز کن

بدون تغییر ظاهر فعلی:

styleهای تکراری را استخراج کن
selectorهای خیلی generic مثل .overflow-y-auto::-webkit-scrollbar را اختصاصی‌تر کن
styleهای inline پرحجم تا حد ممکن منظم‌تر شوند
JSX خواناتر شود
خروجی مورد انتظار

خروجی نهایی باید شامل این‌ها باشد:

ChatbotPage refactor شده
استفاده از همان Header صفحه Feed
hook جدا برای mission session / restore
hook جدا برای chat flow
hook جدا برای typing animation
mapper جدا برای تبدیل ChatMessage به UI model
رفع duplication منطق ارسال پیام
رفع race condition و cleanup timerها
حفظ کامل ظاهر فعلی تا حد ممکن
حفظ کامل contract فعلی با API
اولویت‌ها

اولویت refactor به این ترتیب باشد:

عدم تغییر API contract
پایداری async flow
حذف duplication
استفاده از Header مشترک Feed
ساختار maintainable
بهبود performance
حفظ UI فعلی
تاکید نهایی
APIها را تغییر نده
response shape را تغییر نده
endpointها را تغییر نده
نام فیلدهای backend را تغییر نده
فقط frontend architecture و behavior را اصلاح کن
Header صفحه Chatbot باید از component هدر Feed استفاده کند، نه نسخه تکراری داخل خودش