import React, { useState, useEffect, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { useTranslation } from 'react-i18next';
import { Sparkles, X, Send, Lightbulb, Compass, Award, AlertCircle, Pencil, Loader2 } from 'lucide-react';
const AIHintOverlay = ({
isAIActive,
setIsAIActive,
aiLoading,
submitAICanvasPrompt,
chatMessages = [],
setChatMessages,
chatThreads = [],
activeThreadId = 'default',
setActiveThreadId,
createNewThread,
deleteThread,
renameThread
}) => {
const { t } = useTranslation();
const [prompt, setPrompt] = useState('');
const [loadingStepIndex, setLoadingStepIndex] = useState(0);
const [isEditingThreadTitle, setIsEditingThreadTitle] = useState(false);
const [editTitleVal, setEditTitleVal] = useState('');
const messagesEndRef = useRef(null);
const activeThread = chatThreads.find(t => t.id === activeThreadId) || chatThreads[0] || { title: '' };
const handleStartRename = () => {
setEditTitleVal(activeThread.title);
setIsEditingThreadTitle(true);
};
const handleFinishRename = () => {
if (editTitleVal.trim()) {
renameThread(activeThreadId, editTitleVal.trim());
}
setIsEditingThreadTitle(false);
};
const loadingSteps = [
"Гостримо графітові олівці...",
"Відкриваємо чистий пергамент...",
"Калібруємо творчий компас...",
"Консультуємось з цифровим оракулом...",
"Малюємо контури вузлів...",
"Накладаємо зв'язки...",
"Задуваємо свіже чорнило..."
];
const suggestions = [
{
text: t('canvas.ai_suggest_details', 'Розпиши поточний крок на підзадачі'),
icon: ,
tag: t('canvas.ai_suggest_details_tag', 'Деталізація')
},
{
text: t('canvas.ai_suggest_route', 'Запропонуй альтернативний шлях на випадок сбою'),
icon: ,
tag: t('canvas.ai_suggest_route_tag', 'Альтернатива')
},
{
text: t('canvas.ai_suggest_habits', 'Створи щоденні звички для підкріплення цієї цілі'),
icon: ,
tag: t('canvas.ai_suggest_habits_tag', 'Звички')
}
];
useEffect(() => {
let interval;
if (aiLoading) {
setLoadingStepIndex(0);
interval = setInterval(() => {
setLoadingStepIndex((prev) => (prev + 1) % loadingSteps.length);
}, 3000);
}
return () => clearInterval(interval);
}, [aiLoading]);
// Auto scroll to bottom
useEffect(() => {
if (isAIActive) {
const timer = setTimeout(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, 100);
return () => clearTimeout(timer);
}
}, [chatMessages, aiLoading, isAIActive, activeThreadId]);
const handleSubmit = async (e) => {
if (e) e.preventDefault();
if (!prompt.trim() || aiLoading) return;
const promptToSend = prompt;
setPrompt('');
await submitAICanvasPrompt(promptToSend);
};
const handleKeyDown = (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSubmit();
}
};
const parseInlineMarkdown = (text) => {
const parts = [];
let remaining = text;
const boldRegex = /\*\*([^*]+)\*\*/g;
let match;
let lastIndex = 0;
while ((match = boldRegex.exec(text)) !== null) {
const textBefore = text.substring(lastIndex, match.index);
if (textBefore) parts.push(textBefore);
parts.push({match[1]});
lastIndex = boldRegex.lastIndex;
}
const textAfter = text.substring(lastIndex);
if (textAfter) parts.push(textAfter);
return parts.length > 0 ? parts : text;
};
const renderMarkdown = (text) => {
if (!text) return null;
return text.split('\n').map((line, idx) => {
const cleanLine = line.trim();
if (!cleanLine) return
;
const listMatch = cleanLine.match(/^[\*\-\u2022]\s+(.*)/);
if (listMatch) {
return (
{parseInlineMarkdown(listMatch[1])}
);
}
const numListMatch = cleanLine.match(/^\d+\.\s+(.*)/);
if (numListMatch) {
return (
{parseInlineMarkdown(numListMatch[1])}
);
}
const headingMatch = cleanLine.match(/^(#{1,6})\s+(.*)/);
if (headingMatch) {
const level = headingMatch[1].length;
const headingText = headingMatch[2];
const classes = level === 1 ? "text-xl font-bold font-display mt-3 mb-1.5" :
level === 2 ? "text-lg font-bold font-display mt-2.5 mb-1.5" :
"text-base font-bold font-display mt-2 mb-1";
return {parseInlineMarkdown(headingText)}
;
}
return (
{parseInlineMarkdown(cleanLine)}
);
});
};
return (
{isAIActive && (
<>
{/* Backdrop overlay (no blur) */}
!aiLoading && setIsAIActive(false)}
className="fixed inset-0 bg-primary/20 z-40 cursor-pointer"
/>
{/* Sketchbook Parchment Drawer */}
{/* Spiral binding rings style visualization on the left edge */}
{[...Array(12)].map((_, i) => (
))}
{/* Notebook Margin Line */}
{/* Notebook Paper Lines Pattern */}
{/* Content Container */}
{/* Header */}
TaskFlow AI
{t('canvas.ai_roadmap_strategist', 'Roadmap Strategist')}
{/* Thread Selector Section */}
{isEditingThreadTitle ? (
setEditTitleVal(e.target.value)}
onBlur={handleFinishRename}
onKeyDown={(e) => {
if (e.key === 'Enter') handleFinishRename();
if (e.key === 'Escape') setIsEditingThreadTitle(false);
}}
autoFocus
className="flex-grow bg-transparent text-sm font-bold text-primary border-b-2 border-primary outline-none py-0.5 px-1 font-display"
/>
) : (
▼
)}
{!isEditingThreadTitle && (
)}
{/* Chat Message Area */}
{chatMessages.map((msg) => (
{msg.sender === 'user' ? (
{msg.text}
) : (
{renderMarkdown(msg.text)}
)}
{/* Timestamp */}
{msg.sender === 'user' ? 'Ви' : 'Стратег'}
))}
{/* Loading state showing pencil sketching & steps */}
{aiLoading && (
{/* Pencil writing micro-animation */}
Стратег планує...
Генерація графів
{loadingSteps[loadingStepIndex]}
)}
{/* Suggestions chips (only visible if not loading) */}
{!aiLoading && chatMessages.length === 1 && (
Підказки для старту
{suggestions.map((sug, idx) => (
))}
)}
{/* Chat Input Form */}
>
)}
);
};
export default AIHintOverlay;