import React, { useState, useRef } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkBreaks from 'remark-breaks';
import {
	MainContainer,
	ChatContainer,
	MessageList,
	Message,
	MessageInput,
	TypingIndicator
} from '@chatscope/chat-ui-kit-react';
import '@chatscope/chat-ui-kit-styles/dist/default/styles.min.css';

const { data, plugins, editor, components } = wp;
const { useSelect, useDispatch } = data;
const { Panel, PanelBody } = components;
const { PluginSidebar, PluginSidebarMoreMenuItem } = editor;
const { registerPlugin } = plugins;

/**
 * AI Editor Chat Component
 */
const EditorChatComponent = () => {
	// Default welcome message
	const defaultMessages = [
		{
			message: "Hi! I'm your AI editor assistant. I can help you improve your content. Try asking me to make something more engaging, add a conclusion, or fix the tone.",
			sentTime: "just now",
			sender: "AI Assistant",
			direction: "incoming"
		}
	];

	// Use pre-populated messages if provided (for screenshots/demos), otherwise use default
	const initialMessages = window.saiapEditorChat?.initialMessages?.length > 0
		? window.saiapEditorChat.initialMessages
		: defaultMessages;

	const [messages, setMessages] = useState(initialMessages);
	const [isTyping, setIsTyping] = useState(false);
	const [inputValue, setInputValue] = useState('');
	const [selectedModel, setSelectedModel] = useState('');
	const [selectedProvider, setSelectedProvider] = useState('');
	const messageListRef = useRef(null);

	// Initialize model selection from session storage or defaults
	React.useEffect(() => {
		const savedModel = sessionStorage.getItem('saiap-selected-model');
		const savedProvider = sessionStorage.getItem('saiap-selected-provider');
		
		if (savedModel && savedProvider) {
			setSelectedModel(savedModel);
			setSelectedProvider(savedProvider);
		} else {
			// Use current defaults
			setSelectedModel(window.saiapEditorChat.currentModel);
			setSelectedProvider(window.saiapEditorChat.currentProvider);
		}
	}, []);

	// Get current post content using WordPress data store
	const { postContent, postId } = useSelect((select) => {
		const editor = select('core/editor');
		const post = editor.getCurrentPost();
		return {
			postContent: editor.getEditedPostContent(),
			postId: post ? post.id : 0
		};
	}, []);

	// Get dispatch functions for updating post content
	const { editPost: updatePost } = useDispatch('core/editor');

	/**
	 * Create flattened model options for the dropdown
	 */
	const getModelOptions = () => {
		const models = window.saiapEditorChat.availableModels;
		const options = [];
		
		// Create options in format "Provider: Model Name"
		Object.entries(models).forEach(([provider, providerModels]) => {
			const providerName = provider.charAt(0).toUpperCase() + provider.slice(1);
			Object.entries(providerModels).forEach(([modelId, modelName]) => {
				options.push({
					value: `${provider}:${modelId}`,
					label: `${providerName}: ${modelName}`,
					provider: provider,
					model: modelId
				});
			});
		});
		
		return options;
	};

	/**
	 * Handle model selection change
	 */
	const handleModelChange = (event) => {
		const [provider, model] = event.target.value.split(':');
		setSelectedProvider(provider);
		setSelectedModel(model);
		
		// Save to session storage
		sessionStorage.setItem('saiap-selected-provider', provider);
		sessionStorage.setItem('saiap-selected-model', model);
	};

	/**
	 * Check status of an async chat job
	 */
	const checkChatStatus = async (jobId) => {
		const formData = new FormData();
		formData.append('action', 'saiap_chat_status');
		formData.append('nonce', window.saiapEditorChat.nonce);
		formData.append('job_id', jobId);
		formData.append('post_id', postId);

		const response = await fetch(window.saiapEditorChat.ajaxurl, {
			method: 'POST',
			body: formData
		});
		return response.json();
	};

	/**
	 * Replace the placeholder "Working on it..." message (if present) with a real incoming message.
	 * Otherwise append the message.
	 */
	const replacePlaceholder = (realMessage) => {
		setMessages(prevMessages => {
			const last = prevMessages[prevMessages.length - 1];
			if (last && last._placeholder) {
				return [...prevMessages.slice(0, -1), realMessage];
			}
			return [...prevMessages, realMessage];
		});
	};

	/**
	 * Handle the result of a completed chat job
	 */
	const handleChatResult = (data) => {
		const aiMessage = {
			message: data.chat_message,
			sentTime: "just now",
			sender: "AI Assistant",
			direction: "incoming"
		};
		replacePlaceholder(aiMessage);

		// Check if the AI made any edits
		if (data.has_edit && data.edited_content) {
			// Update post content with AI edits
			updatePost({ content: data.edited_content });

			// Show a separate "Post edited" message
			const editConfirmation = {
				message: "Post edited.",
				sentTime: "just now",
				sender: "System",
				direction: "incoming"
			};
			setMessages(prevMessages => [...prevMessages, editConfirmation]);
		}

		// Update featured image if one was set
		if (data.featured_media) {
			updatePost({ featured_media: data.featured_media });
		}
	};

	/**
	 * Handle sending a message
	 */
	const handleSend = async (message) => {
		if (!message.trim()) {
			return;
		}

		// Clear input
		setInputValue('');

		// Add user message
		const userMessage = {
			message: message,
			sentTime: "just now",
			sender: "You",
			direction: "outgoing"
		};

		// Placeholder assistant message so the user sees an immediate acknowledgment
		// even before the backend responds. Replaced with the real reply (or error) later.
		const placeholderMessage = {
			message: "_Working on it… this can take up to a minute._",
			sentTime: "just now",
			sender: "AI Assistant",
			direction: "incoming",
			_placeholder: true
		};

		setMessages(prevMessages => [...prevMessages, userMessage, placeholderMessage]);
		setIsTyping(true);

		try {
			// Build conversation history (exclude system messages, map to role/content)
			const history = messages
				.filter(m => m.sender !== 'System')
				.map(m => ({
					role: m.direction === 'outgoing' ? 'user' : 'assistant',
					content: m.message
				}));

			// Send the request to backend
			const formData = new FormData();
			formData.append('action', 'saiap_chat_message');
			formData.append('nonce', window.saiapEditorChat.nonce);
			formData.append('message', message);
			formData.append('content', postContent);
			formData.append('post_id', postId);
			formData.append('provider', selectedProvider);
			formData.append('model', selectedModel);
			formData.append('history', JSON.stringify(history));

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

			const data = await response.json();

			if (data.success) {
				// Check if this is an async response with job_id
				if (data.data.async && data.data.job_id) {
					// Start polling for job completion
					const POLL_INTERVAL = 3000; // 3 seconds
					const MAX_POLLS = 60; // 3 minutes max
					let pollCount = 0;

					const pollId = setInterval(async () => {
						pollCount++;
						try {
							const statusResult = await checkChatStatus(data.data.job_id);

							if (statusResult.success && statusResult.data.status === 'completed') {
								clearInterval(pollId);
								setIsTyping(false);
								handleChatResult(statusResult.data);
							} else if (!statusResult.success || statusResult.data.status === 'error') {
								clearInterval(pollId);
								setIsTyping(false);
								replacePlaceholder({
									message: statusResult.data?.message || window.saiapEditorChat.i18n.errorGeneral,
									sentTime: "just now",
									sender: "AI Assistant",
									direction: "incoming"
								});
							} else if (pollCount >= MAX_POLLS) {
								clearInterval(pollId);
								setIsTyping(false);
								replacePlaceholder({
									message: 'Request timed out. The AI is taking longer than expected. Please try again.',
									sentTime: "just now",
									sender: "AI Assistant",
									direction: "incoming"
								});
							}
							// else: still pending, keep polling
						} catch (pollError) {
							console.error('Polling error:', pollError);
							clearInterval(pollId);
							setIsTyping(false);
							replacePlaceholder({
								message: window.saiapEditorChat.i18n.errorConnection,
								sentTime: "just now",
								sender: "AI Assistant",
								direction: "incoming"
							});
						}
					}, POLL_INTERVAL);
				} else {
					// Synchronous response (fallback for local provider)
					setIsTyping(false);
					handleChatResult(data.data);
				}
			} else {
				// Add error message
				setIsTyping(false);
				replacePlaceholder({
					message: data.data?.message || window.saiapEditorChat.i18n.errorGeneral,
					sentTime: "just now",
					sender: "AI Assistant",
					direction: "incoming"
				});
			}
		} catch (error) {
			console.error('Chat error:', error);

			replacePlaceholder({
				message: window.saiapEditorChat.i18n.errorConnection,
				sentTime: "just now",
				sender: "AI Assistant",
				direction: "incoming"
			});
			setIsTyping(false);
		}
	};

	/**
	 * Handle input change
	 */
	const handleInputChange = (innerHtml, textContent) => {
		setInputValue(textContent);
	};

	/**
	 * Handle key down in input
	 */
	const handleKeyDown = (event) => {
		if (event.key === 'Enter' && !event.shiftKey) {
			event.preventDefault();
			handleSend(inputValue);
		}
		// Allow Shift+Enter to create new line (default behavior)
	};

	return (
		<PanelBody 
			title={window.saiapEditorChat.i18n.chatTitle} 
			initialOpen={true}
		>
			<div className="saiap-chat-body-wrapper">
				<MainContainer>
					<ChatContainer>
						<MessageList 
							ref={messageListRef}
							typingIndicator={isTyping ? <TypingIndicator content={window.saiapEditorChat.i18n.thinking} /> : null}
						>
							{messages.map((message, i) => (
								<Message 
									key={i} 
									model={message}
								>
									<Message.CustomContent>
										<ReactMarkdown
											remarkPlugins={[remarkBreaks]}
											linkTarget="_blank"
											components={{
												a: ({ node, ...props }) => (
													<a {...props} target="_blank" rel="noopener noreferrer" />
												)
											}}
										>
											{message.message}
										</ReactMarkdown>
									</Message.CustomContent>
								</Message>
							))}
						</MessageList>
						<MessageInput 
							placeholder={window.saiapEditorChat.i18n.placeholder}
							onSend={handleSend}
							onChange={handleInputChange}
							onKeyDown={handleKeyDown}
							value={inputValue}
							disabled={isTyping}
							attachButton={false}
							sendButton={true}
							style={{
								fontSize: "14px"
							}}
						/>
					</ChatContainer>
				</MainContainer>
			</div>
			{/* Model Selection Dropdown */}
			<div className="saiap-model-selector" style={{
				marginBottom: '16px',
				padding: '12px',
				backgroundColor: '#f6f7f7',
				border: '1px solid #ddd',
				borderRadius: '4px'
			}}>
				<select 
					id="saiap-model-select"
					value={`${selectedProvider}:${selectedModel}`}
					onChange={handleModelChange}
					style={{
						width: '100%',
						padding: '2px 8px',
						fontSize: '12px',
						border: '1px solid #8c8f94',
						borderRadius: '3px',
						backgroundColor: '#fff'
					}}
				>
					{getModelOptions().map((option) => (
						<option key={option.value} value={option.value}>
							{option.label}
						</option>
					))}
				</select>
			</div>
		</PanelBody>
	);
};

/**
 * Register the plugin
 */
const EditorChatPlugin = () => {
	return (
		<>
			<PluginSidebarMoreMenuItem
				target="saiap-editor-chat-sidebar"
				icon="format-chat"
			>
				{window.saiapEditorChat.i18n.toggleChat}
			</PluginSidebarMoreMenuItem>
			<PluginSidebar
				name="saiap-editor-chat-sidebar"
				title={window.saiapEditorChat.i18n.chatTitle}
				icon="format-chat"
			>
				<div className="saiap-editor-chat-wrapper">
					<EditorChatComponent />
					<ImageSearchWidget />
				</div>
			</PluginSidebar>
		</>
	);
};

// Register the plugin with WordPress
registerPlugin('saiap-editor-chat', {
	render: EditorChatPlugin,
	icon: 'format-chat'
});

// Export for potential testing
export default EditorChatComponent;

/**
 * Lightweight Image Search Widget injected below the chat component
 */
const ImageSearchWidget = () => {
  const [isOpen, setIsOpen] = React.useState(false);
  const [isLoading, setIsLoading] = React.useState(false);
  const [error, setError] = React.useState('');
  const [results, setResults] = React.useState([]);
  const [selectedIndex, setSelectedIndex] = React.useState(-1);

  const { postContent, postTitle, postId } = useSelect((select) => {
    const editor = select('core/editor');
    const post = editor.getCurrentPost();
    return {
      postContent: editor.getEditedPostContent(),
      postTitle: post?.title || '',
      postId: post ? post.id : 0
    };
  }, []);

  const guessQuery = () => {
    if (postTitle && postTitle.trim().length > 0) return postTitle.trim();
    const text = (postContent || '').replace(/<[^>]+>/g, ' ').trim();
    return text.split(/\s+/).slice(0, 6).join(' ');
  };

  const searchImages = async () => {
    setIsLoading(true);
    setError('');
    try {
      const q = guessQuery();
      const url = `${window.saiapEditorChat.restUrl}/image-search?q=${encodeURIComponent(q)}&num=3`;
      const resp = await fetch(url, { headers: { 'X-WP-Nonce': window.saiapEditorChat.restNonce } });
      const data = await resp.json();
      if (!resp.ok || !data?.results) throw new Error(data?.error || data?.message || window.saiapEditorChat.i18n.imageSearchError);
      setResults(data.results);
      setSelectedIndex(-1);
    } catch (e) {
      setError(window.saiapEditorChat.i18n.imageSearchError);
    } finally {
      setIsLoading(false);
    }
  };

  const selectImage = async () => {
    if (selectedIndex < 0 || !results[selectedIndex]) return;
    const chosen = results[selectedIndex];
    try {
      const resp = await fetch(`${window.saiapEditorChat.restUrl}/image-select`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-WP-Nonce': window.saiapEditorChat.restNonce
        },
        body: JSON.stringify({
          postId: postId,
          imageUrl: chosen.fullImageUrl,
          alt: chosen.title || '',
          sourceAttribution: {
            sourcePageUrl: chosen.sourcePageUrl || '',
            title: chosen.title || ''
          }
        })
      });
      if (!resp.ok) {
        const err = await resp.json().catch(() => ({}));
        throw new Error(err?.error || err?.message || 'failed');
      }
      setIsOpen(false);
      setResults([]);
      setSelectedIndex(-1);
      // Best-effort toast
      if (window.wp && wp.data && wp.data.dispatch) {
        try { wp.data.dispatch('core/notices').createNotice('success', window.saiapEditorChat.i18n.imageSetSuccess, { isDismissible: true }); } catch (e) {}
      }
    } catch (e) {
      setError(window.saiapEditorChat.i18n.errorGeneral);
    }
  };

  return (
    <div className="saiap-image-widget" style={{ padding: '12px' }}>
      <button className="button" onClick={() => { setIsOpen((o) => !o); if (!isOpen) { searchImages(); } }}>
        {window.saiapEditorChat.i18n.findImages}
      </button>
      {isOpen && (
        <div className="saiap-image-picker" style={{ marginTop: '12px' }}>
          {isLoading && <div>{window.saiapEditorChat.i18n.thinking}</div>}
          {error && <div style={{ color: '#b32d2e' }}>{error}</div>}
          {!isLoading && !error && (
            <div className="saiap-image-picker-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '8px' }}>
              {results.map((r, idx) => (
                <div key={idx} className={`saiap-image-card ${selectedIndex === idx ? 'saiap-image-selected' : ''}`} style={{ border: selectedIndex === idx ? '2px solid #2271b1' : '1px solid #ddd', padding: '4px', cursor: 'pointer' }} onClick={() => setSelectedIndex(idx)}>
                  <img src={r.thumbnailUrl || r.fullImageUrl} alt={r.title || ''} style={{ width: '100%', height: '100px', objectFit: 'cover' }} />
                  <div style={{ fontSize: '11px', marginTop: '4px' }} title={r.title}>{r.title}</div>
                </div>
              ))}
            </div>
          )}
          <div style={{ marginTop: '8px' }}>
            <button className="button button-primary" disabled={selectedIndex < 0} onClick={selectImage}>
              {window.saiapEditorChat.i18n.useAsFeatured}
            </button>
          </div>
        </div>
      )}
    </div>
  );
};