/**
 * Frontend App Component
 */
import { useState, useRef, useEffect } from 'react';

const App = () => {
	const [isOpen, setIsOpen] = useState(false);
	const [content, setContent] = useState('');
	const [isProcessing, setIsProcessing] = useState(false);
	const [responses, setResponses] = useState([]);
	const [ error, setError ] = useState( null );
	const [conversationId, setConversationId] = useState(() => {
		// Load conversation ID from localStorage on mount
		return localStorage.getItem('websamurai_conversation_id') || null;
	});
	const [pollingTimeout, setPollingTimeout] = useState(null);
	const responsesEndRef = useRef(null);

	const scrollToBottom = () => {
		responsesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
	};

	// Load conversation from GraphQL on mount if we have an ID
	useEffect(() => {
		if (conversationId) {
			// Check if conversation is older than 1 hour
			const storedUpdatedDate = localStorage.getItem('websamurai_conversation_updated_date');

			if (storedUpdatedDate) {
				const updatedDateMs = parseInt(storedUpdatedDate, 10);
				const currentTimeMs = Date.now();
				const ageInSeconds = (currentTimeMs - updatedDateMs) / 1000;

				// If conversation is older than 1 hour (3600 seconds), clear it
				if (ageInSeconds > 3600) {
					// Clear stale conversation
					setConversationId(null);
					setResponses([]);
					localStorage.removeItem('websamurai_conversation_id');
					localStorage.removeItem('websamurai_conversation_updated_date');
					return;
				}
			}

			pollConversation(conversationId);
			startPolling(conversationId);
		}
	}, []);

	// Scroll to bottom when responses change
	useEffect(() => {
		scrollToBottom();
	}, [responses]);

	// Save conversation ID to localStorage whenever it changes
	useEffect(() => {
		if (conversationId) {
			localStorage.setItem('websamurai_conversation_id', conversationId);
		} else {
			localStorage.removeItem('websamurai_conversation_id');
		}
	}, [conversationId]);

	// Cleanup polling timeout on unmount
	useEffect(() => {
		return () => {
			if (pollingTimeout) {
				clearTimeout(pollingTimeout);
			}
		};
	}, [pollingTimeout]);

	const createConversation = async (userMessage) => {
		try {
			setError( null );
			let context = {
				currentType: window.samurAiFrontend.currentType,
				currentID: window.samurAiFrontend.currentID,
				slug: window.samurAiFrontend.slug,
				locationType: window.samurAiFrontend.locationType,
			};

			const formData = new FormData();
			formData.append('action', 'websamurai_create_conversation');
			formData.append('nonce', window.samurAiFrontend.nonce);
			formData.append('subject', userMessage.substring(0, 50));
			formData.append('type', 'WebSamurai');
			formData.append('prompt', userMessage);
			formData.append('context', JSON.stringify( context ) );

			const response = await fetch(window.samurAiFrontend.ajaxUrl, {
				method: 'POST',
				body: formData,
			});

			const data = await response.json();

			if (data.success) {
				const conversation = data.data.conversation;
				setConversationId(conversation.id);
				startPolling(conversation.id);
				return conversation;
			} else {
				console.error('Error creating conversation:', data.data?.message);
				setError( data.data?.message || 'Error creating conversation' );
				return null;
			}
		} catch (error) {
			console.error('Error creating conversation:', error);
			return null;
		}
	};

	const updateConversation = async (convId, userMessage) => {
		try {
			setError( null );
			const formData = new FormData();
			formData.append('action', 'websamurai_update_conversation');
			formData.append('nonce', window.samurAiFrontend.nonce);
			formData.append('conversation_id', convId);
			formData.append('message', userMessage);

			const response = await fetch(window.samurAiFrontend.ajaxUrl, {
				method: 'POST',
				body: formData,
			});

			const data = await response.json();
			if ( data.success ) {
				const conversation = data.data.conversation;
				// Continue polling for the updated conversation
				startPolling(conversation.id);
				return conversation;
			} else {
				console.error('Error updating conversation:', data.data?.message);
				setError( data.data?.message || 'Error updating conversation' );
				return null;
			}
		} catch (error) {
			console.error('Error updating conversation:', error);
			return null;
		}
	};

	const pollConversation = async (convId) => {
		try {
			const formData = new FormData();
			formData.append('action', 'websamurai_get_conversation');
			formData.append('nonce', window.samurAiFrontend.nonce);
			formData.append('conversation_id', convId);

			const response = await fetch(window.samurAiFrontend.ajaxUrl, {
				method: 'POST',
				body: formData,
			});

			const data = await response.json();

			if (data.success) {
				const conversation = data.data.conversation;

				// Store UpdatedDate in localStorage to track conversation age
				if (conversation.UpdatedDate) {
					localStorage.setItem('websamurai_conversation_updated_date', conversation.UpdatedDate);
				}

				// Update responses from the Prompt field
				if (conversation.Prompt && conversation.Prompt.prompts) {
					const newResponses = [];
					conversation.Prompt.prompts.forEach((prompt) => {
						newResponses.push({
							type: prompt.role === 'user' ? 'user' : 'ai',
							text: prompt.content,
							timestamp: new Date().toLocaleTimeString(),
						});
					});
					setResponses(newResponses);
				}

				// If DoneResponse is true, stop polling
				if (conversation.DoneResponse) {
					if (pollingTimeout) {
						clearTimeout(pollingTimeout);
						setPollingTimeout(null);
					}
					setIsProcessing(false);
				} else {
					// Schedule next poll after 2 seconds
					const timeout = setTimeout(() => {
						pollConversation(convId);
					}, 2000);
					setPollingTimeout(timeout);
				}

				return conversation;
			} else {
				console.error('Error polling conversation:', data.data?.message);
				return null;
			}
		} catch (error) {
			console.error('Error polling conversation:', error);
			return null;
		}
	};

	const startPolling = (convId) => {
		// Clear existing timeout if any
		if (pollingTimeout) {
			clearTimeout(pollingTimeout);
		}

		// Start polling immediately
		pollConversation(convId);
	};

	const handleToggle = () => {
		setIsOpen(!isOpen);
	};

	const handleSubmit = async () => {
		if (!content.trim()) {
			alert('Please enter some text to send to AI');
			return;
		}

		setIsProcessing(true);

		// Add user message to responses
		const userMessage = {
			type: 'user',
			text: content,
			timestamp: new Date().toLocaleTimeString(),
		};
		setResponses((prev) => [...prev, userMessage]);

		const messageContent = content;
		setContent('');

		try {
			// If this is the first message, create a new conversation
			let ret = null;
			if (!conversationId) {
				ret = await createConversation(messageContent);
			} else {
				// Update existing conversation with new message
				ret = await updateConversation(conversationId, messageContent);
			}
			if( ! ret ) { 
				setIsProcessing(false);
			}
		} catch (error) {
			console.error('Error:', error);
			const errorMessage = {
				type: 'error',
				text: 'Failed to communicate with server',
				timestamp: new Date().toLocaleTimeString(),
			};
			setResponses((prev) => [...prev, errorMessage]);
			setIsProcessing(false);
		}
	};

	const handleKeyPress = (e) => {
		if (e.key === 'Enter' && !e.shiftKey) {
			e.preventDefault();
			handleSubmit();
		}
	};

	const handleClose = () => {
		setIsOpen(false);
	};

	const handleClear = () => {
		// Stop polling if active
		if (pollingTimeout) {
			clearTimeout(pollingTimeout);
			setPollingTimeout(null);
		}

		// Reset conversation state
		setResponses([]);
		setConversationId(null);
		setIsProcessing(false);
		setError( null );

		// Remove UpdatedDate from localStorage
		localStorage.removeItem('websamurai_conversation_updated_date');
	};

	return (
		<>
			{/* Sticky Tab */}
			<div
				className={`websamurai-edit-tab ${isOpen ? 'open' : ''}`}
				onClick={handleToggle}
			>
				<span className="tab-text">Edit with AI</span>
			</div>

			{/* Slide-out Panel */}
			<div className={`websamurai-edit-panel ${isOpen ? 'open' : ''}`}>
				<div className="panel-header">
					<h3>Edit with AI</h3>
					<button
						className="close-button"
						onClick={handleClose}
						aria-label="Close"
					>
						×
					</button>
				</div>

				<div className="panel-content">
					{/* Responses Area */}
					<div className="responses-area">
						{responses.length === 0 ? (
							<div className="empty-state">
								<p>Ask the AI to help you edit or create content...</p>
							</div>
						) : (
							<>
								<div className="responses-header">
									<span className="responses-count">
										{responses.length} message{responses.length !== 1 ? 's' : ''}
									</span>
									<button className="clear-button" onClick={handleClear}>
										Clear
									</button>
								</div>
								<div className="responses-list">
									{responses.map((response, index) => {
										let resptext = response.text;
										if( ! resptext && response.content ) {
											resptext = response.content;
										}
										if( typeof resptext === 'string' ) {
											resptext = resptext.split('\n').map((line, i) => (
												<span key={i}>
													{line}
													<br />
												</span>
											));
										} else if( typeof resptext === 'object' ) {
											if( resptext.errors ) {
												resptext = resptext.errors.map((err, i) => (
													<span key={i} className="error">
														{err}
														<br />
													</span>
												));
											} else if( Array.isArray( resptext ) ) {
												resptext = resptext.map( txt => {
													if( ! txt || txt.type === 'mcp_tool_use' || txt.type === 'mcp_tool_result' ) {
														return null;
													}
													let out = txt.text;
													if( ! out && txt.content ) {
														out = txt.content;
													}
													if( ! out ) {
														return null;
													}
													if( Array.isArray( out ) ) {
														out = out.map( (line ) => line.text ).join( '' );
													}
													
													if( typeof out !== 'string' ) {
														return '[Unsupported response format]';
													}
													return out.split( '\n' ).map( (line, i) => (
														<span key={i}>
															{line}
															<br />
														</span>
													) ) 
												} );
											} else {
												resptext = JSON.stringify( resptext );
											}
											
										} else {
											resptext = 'Unexpected response format';
										}
										return <div key={index} className={`response-message ${response.type}`}>
											<div className="message-header">
												<span className="message-label">
													{response.type === 'user' ? 'You' : response.type === 'ai' ? 'AI' : 'Error'}
												</span>
												<span className="message-time">{response.timestamp}</span>
											</div>
											<div className="message-text">{resptext}</div>
										</div>
									} )}

									{/* Thinking Animation */}
									{isProcessing && (
										<div className="response-message ai thinking">
											<div className="message-header">
												<span className="message-label">AI</span>
											</div>
											<div className="message-text">
												<div className="thinking-animation">
													<span className="dot"></span>
													<span className="dot"></span>
													<span className="dot"></span>
												</div>
											</div>
										</div>
									)}
									{ error && (
										<div className="response-message error">
											<div className="message-header">
												<span className="message-label">Error</span>
											</div>
											<div className="message-text">
												{ error }
											</div>
										</div>
									) }

									<div ref={responsesEndRef} />
								</div>
							</>
						)}
					</div>

					{/* Input Area */}
					<div className="input-area">
						<textarea
							id="ai-input"
							className="ai-textarea"
							value={content}
							onChange={(e) => setContent(e.target.value)}
							onKeyPress={handleKeyPress}
							placeholder="Type your message... (Press Enter to send, Shift+Enter for new line)"
							rows={3}
							disabled={isProcessing}
						/>

						<div className="panel-actions">
							<button
								className="submit-button"
								onClick={handleSubmit}
								disabled={isProcessing || !content.trim()}
							>
								{isProcessing ? 'Sending...' : 'Send'}
							</button>
						</div>
					</div>
				</div>
			</div>

			{/* Overlay */}
			{isOpen && (
				<div
					className="websamurai-overlay"
					onClick={handleClose}
				/>
			)}
		</>
	);
};

export default App;
