import React, { useState, useEffect, useCallback, useRef } from 'react';
import './IntentEditor.css';
import { apiService, Intent, ExtractedStep } from '../../services/api';
import { IntentActionHandlers, IntentActionStatus } from '../../types/intentActions';
import * as mammoth from 'mammoth/mammoth.browser';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeRaw from 'rehype-raw';

interface IntentEditorProps {
	onRegisterActions?: (handlers: IntentActionHandlers | null) => void;
	onStatusChange?: (status: IntentActionStatus) => void;
	onComplete?: (steps: ExtractedStep[]) => void;
}

const IntentEditor: React.FC<IntentEditorProps> = ({ onRegisterActions, onStatusChange, onComplete }) => {
	const [title, setTitle] = useState('新建意图编制');
	const [content, setContent] = useState('');
	const [currentIntent, setCurrentIntent] = useState<Intent | null>(null);
	const [isSaving, setIsSaving] = useState(false);
	const [isGenerating, setIsGenerating] = useState(false);
	const [isChecking, setIsChecking] = useState(false);
	const [isExtracting, setIsExtracting] = useState(false);
	const [checkResult, setCheckResult] = useState<any>(null);
	const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
	const [viewMode, setViewMode] = useState<'edit' | 'preview' | 'split'>('edit');
	const fileInputRef = useRef<HTMLInputElement>(null);
	const textareaRef = useRef<HTMLTextAreaElement>(null);

	useEffect(() => {
		onStatusChange?.({
			isSaving,
			isGenerating,
			isChecking,
		});
	}, [onStatusChange, isSaving, isGenerating, isChecking]);

	// 显示消息
	const showMessage = (type: 'success' | 'error', text: string) => {
		setMessage({ type, text });
		setTimeout(() => setMessage(null), 3000);
	};

	// 保存意图
	const handleSave = useCallback(async () => {
		if (!title.trim()) {
			showMessage('error', '请输入标题');
			return;
		}

		setIsSaving(true);
		try {
			if (currentIntent) {
				// 更新
				const updated = await apiService.updateIntent(currentIntent.id, { title, content });
				setCurrentIntent(updated);
				showMessage('success', '保存成功');
			} else {
				// 创建
				const created = await apiService.createIntent({ title, content });
				setCurrentIntent(created);
				showMessage('success', '创建成功');
			}
		} catch (error) {
			showMessage('error', '保存失败');
		} finally {
			setIsSaving(false);
		}
	}, [title, content, currentIntent]);

	// AI 生成内容
	const handleGenerate = useCallback(async () => {
		// 如果文本框有内容，则基于当前内容生成测试规划
		if (content.trim()) {
			setIsGenerating(true);
			try {
				const result = await apiService.generateTestPlan(content, title || '用户输入');

				if (result.success) {
					setContent(result.content);
					showMessage('success', 'AI 测试规划生成完成');
				} else {
					showMessage('error', result.error || 'AI 生成失败');
				}
			} catch (error) {
				showMessage('error', '网络错误，请确保后端服务已启动');
			} finally {
				setIsGenerating(false);
			}
		} else {
			// 如果文本框为空，使用原有的意图编制生成
			setIsGenerating(true);
			try {
				const result = await apiService.generateIntentContent({
					test_type: '功能测试',
					test_target: title || '待定义的测试目标',
				});

				if (result.success) {
					setContent(result.content);
					showMessage('success', 'AI 生成完成');
				} else {
					showMessage('error', result.error || 'AI 生成失败');
				}
			} catch (error) {
				showMessage('error', '网络错误，请确保后端服务已启动');
			} finally {
				setIsGenerating(false);
			}
		}
	}, [title, content]);

	// AI 检查内容
	const handleCheck = useCallback(async () => {
		if (!content.trim()) {
			showMessage('error', '请先输入或生成内容');
			return;
		}

		setIsChecking(true);
		setCheckResult(null);
		try {
			const result = await apiService.checkContent({
				content,
				intent_id: currentIntent?.id,
			});

			if (result.success) {
				setCheckResult(result.result);
			} else {
				showMessage('error', result.error || 'AI 检查失败');
			}
		} catch (error) {
			showMessage('error', '网络错误');
		} finally {
			setIsChecking(false);
		}
	}, [content, currentIntent]);

	// 新建意图
	const handleNew = useCallback(() => {
		setTitle('新建意图编制');
		setContent('');
		setCurrentIntent(null);
		setCheckResult(null);
	}, []);

	const handleOpen = useCallback(() => {
		fileInputRef.current?.click();
	}, []);

	const extractTitleAndContent = useCallback((text: string, fallbackTitle: string) => {
		const lines = text.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
		if (lines.length === 0) {
			return { parsedTitle: fallbackTitle, parsedContent: text };
		}
		const first = lines[0];
		const parsedTitle = first.replace(/^#+\s*/, '') || fallbackTitle;
		const parsedContent = lines.slice(1).join('\n').trim();
		return { parsedTitle, parsedContent: parsedContent || text };
	}, []);

	const handleFileChange = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
		const file = event.target.files?.[0];
		if (!file) return;

		const fileName = file.name.replace(/\.[^/.]+$/, '');
		const ext = `.${file.name.split('.').pop() || ''}`.toLowerCase();

		try {
			if (ext === '.docx') {
				const buffer = await file.arrayBuffer();
				const result = await mammoth.extractRawText({ arrayBuffer: buffer });
				const fileContent = result.value || '';
				const { parsedContent } = extractTitleAndContent(
					fileContent,
					fileName || '新建意图编制'
				);
				setTitle(fileName || '新建意图编制');
				setContent(parsedContent);
				setCurrentIntent(null);
				setCheckResult(null);
				showMessage('success', '文件已打开');
			} else if (['.pdf', '.png', '.jpg', '.jpeg', '.bmp', '.tif', '.tiff', '.webp'].includes(ext)) {
				const parsed = await apiService.parseIntentFile(file);
				setTitle(fileName || '新建意图编制');
				setContent(parsed.content || '');
				setCurrentIntent(null);
				setCheckResult(null);
				showMessage('success', '文件已解析并打开');
			} else {
				const reader = new FileReader();
				reader.onload = () => {
					const fileContent = typeof reader.result === 'string' ? reader.result : '';
					const { parsedContent } = extractTitleAndContent(
						fileContent,
						fileName || '新建意图编制'
					);
					setTitle(fileName || '新建意图编制');
					setContent(parsedContent);
					setCurrentIntent(null);
					setCheckResult(null);
					showMessage('success', '文件已打开');
				};
				reader.onerror = () => {
					showMessage('error', '文件读取失败');
				};
				reader.readAsText(file, 'utf-8');
			}
		} catch (error) {
			const errorMessage = error instanceof Error ? error.message : '文件解析失败';
			showMessage('error', errorMessage);
		} finally {
			event.target.value = '';
		}
	}, []);

	const handleExport = useCallback(() => {
		if (!title.trim() && !content.trim()) {
			showMessage('error', '没有可导出的内容');
			return;
		}

		const exportContent = `# ${title || '未命名意图'}\n\n${content || ''}`;
		const blob = new Blob([exportContent], { type: 'text/markdown;charset=utf-8' });
		const url = URL.createObjectURL(blob);
		const link = document.createElement('a');
		const safeTitle = (title || 'intent').replace(/[\\/:*?"<>|]/g, '_');
		link.href = url;
		link.download = `${safeTitle}.md`;
		link.click();
		URL.revokeObjectURL(url);
		showMessage('success', '导出完成');
	}, [title, content]);

	const isMarkdownContent = useCallback((text: string) => {
		return /(^|\n)#{1,6}\s+|\|.+\||```|\*\*|__|\[.+\]\(.+\)|^\s*[-*+]\s+/m.test(text);
	}, []);

	// 点击预览区域时，通过搜索文本内容来定位到源码
	const handlePreviewClick = useCallback((event: React.MouseEvent) => {
		if (!textareaRef.current || viewMode === 'preview') return;

		const target = event.target as HTMLElement;
		// 获取点击元素的纯文本内容
		const clickedText = target.textContent?.trim();
		if (!clickedText || clickedText.length < 2) return;

		// 在源码中搜索这段文本
		const searchText = clickedText.slice(0, Math.min(clickedText.length, 50)); // 取前50字符搜索
		const index = content.indexOf(searchText);
		
		if (index !== -1) {
			const textarea = textareaRef.current;
			const endIndex = index + searchText.length;
			
			// 方法：按字符位置的比例来计算滚动位置
			// 这比依赖行高更可靠
			const totalLength = content.length;
			const ratio = index / totalLength;
			const maxScroll = textarea.scrollHeight - textarea.clientHeight;
			
			// 目标位置，稍微往上偏移一点让选中内容在视口中间偏上
			const targetScrollTop = Math.max(0, ratio * textarea.scrollHeight - textarea.clientHeight / 3);
			
			// 设置滚动位置
			textarea.scrollTop = Math.min(targetScrollTop, maxScroll);
			
			// 使用 setTimeout 确保滚动完成后再设置选区和焦点
			setTimeout(() => {
				textarea.focus();
				textarea.setSelectionRange(index, endIndex);
				
				// 如果浏览器自动调整了滚动位置，我们再修正一次
				const currentScroll = textarea.scrollTop;
				const expectedScroll = Math.min(targetScrollTop, maxScroll);
				if (Math.abs(currentScroll - expectedScroll) > 50) {
					textarea.scrollTop = expectedScroll;
				}
			}, 10);
		}
	}, [content, viewMode]);

	useEffect(() => {
		onRegisterActions?.({
			onNew: handleNew,
			onOpen: handleOpen,
			onSave: handleSave,
			onGenerate: handleGenerate,
			onCheck: handleCheck,
			onExport: handleExport,
		});

		return () => {
			onRegisterActions?.(null);
		};
	}, [onRegisterActions, handleNew, handleOpen, handleSave, handleGenerate, handleCheck, handleExport]);

	return (
		<div className="intent-editor">
			<input
				ref={fileInputRef}
				type="file"
				accept=".md,.txt,.markdown,.docx,.pdf,.png,.jpg,.jpeg,.bmp,.tif,.tiff,.webp"
				onChange={handleFileChange}
				style={{ display: 'none' }}
			/>
			{/* 消息提示 */}
			{message && (
				<div className={`editor-message ${message.type}`}>
					{message.text}
				</div>
			)}

			{/* 编辑区域 */}
			<div className="editor-content">
				<div className="editor-main">
					<div className="editor-title-row">
						<input
							type="text"
							className="editor-title selectable"
							value={title}
							onChange={(e) => setTitle(e.target.value)}
							placeholder="请输入意图标题..."
						/>
						<div className="editor-title-actions">
							{isMarkdownContent(content) && (
								<div className="view-mode-toggle">
									<button
										className={`toggle-btn ${viewMode === 'edit' ? 'active' : ''}`}
										onClick={() => setViewMode('edit')}
										title="仅编辑"
									>
										编辑
									</button>
									<button
										className={`toggle-btn ${viewMode === 'split' ? 'active' : ''}`}
										onClick={() => setViewMode('split')}
										title="分屏预览"
									>
										分屏
									</button>
									<button
									className={`toggle-btn ${viewMode === 'preview' ? 'active' : ''}`}
									onClick={() => setViewMode('preview')}
									title="仅预览"
								>
									预览
								</button>
							</div>
							)}
							<button 
								className={`complete-btn ${isExtracting ? 'loading' : ''}`}
								onClick={async () => {
									if (!content.trim()) {
										showMessage('error', '请先输入或生成意图编制内容');
										return;
									}
									setIsExtracting(true);
									try {
										const result = await apiService.extractSteps(content, title);
										if (result.success && result.steps.length > 0) {
											showMessage('success', `已提取 ${result.steps.length} 个测试步骤`);
											onComplete?.(result.steps);
										} else {
											showMessage('error', result.error || '未能提取到测试步骤');
										}
									} catch (error) {
										showMessage('error', '网络错误，请确保后端服务已启动');
									} finally {
										setIsExtracting(false);
									}
								}}
								disabled={isExtracting}
								title="完成编制并提交到下一流程"
							>
								{isExtracting ? (
									<span className="loading-spinner" />
								) : (
									<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
										<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
										<polyline points="22 4 12 14.01 9 11.01" />
									</svg>
								)}
								{isExtracting ? '提取中...' : '完成编制'}
							</button>
						</div>
					</div>
					
					<div className={`editor-body mode-${viewMode}`}>
						{(viewMode === 'edit' || viewMode === 'split') && (
							<textarea
								ref={textareaRef}
								className="editor-textarea selectable"
								value={content}
								onChange={(e) => setContent(e.target.value)}
								placeholder="请输入意图编制内容，或使用 AI 生成..."
							/>
						)}
						{viewMode === 'split' && <div className="editor-divider" />}
						{(viewMode === 'preview' || viewMode === 'split') && (
							<div 
								className="editor-markdown selectable clickable-preview"
								onClick={handlePreviewClick}
								title="点击文字可定位到左侧编辑器对应位置"
							>
								<ReactMarkdown 
									remarkPlugins={[remarkGfm]} 
									rehypePlugins={[rehypeRaw]}
								>
									{content || '暂无预览内容'}
								</ReactMarkdown>
							</div>
						)}
					</div>
				</div>

				{/* AI 检查结果面板 */}
				{checkResult && (
					<div className="check-result-panel">
						<div className="check-header">
							<span className="check-title">AI 检查结果</span>
							<button className="close-btn" onClick={() => setCheckResult(null)}>
								✕
							</button>
						</div>
						<div className="check-body">
							<div className={`check-status ${checkResult.passed ? 'passed' : 'failed'}`}>
								<span className="status-icon">{checkResult.passed ? '✓' : '✗'}</span>
								<span className="status-text">
									{checkResult.passed ? '检查通过' : '需要改进'}
								</span>
								<span className="status-score">得分: {checkResult.score}/100</span>
							</div>

							{checkResult.issues?.length > 0 && (
								<div className="check-section">
									<div className="section-title">发现的问题</div>
									<ul className="issue-list">
										{checkResult.issues.map((issue: string, idx: number) => (
											<li key={idx}>{issue}</li>
										))}
									</ul>
								</div>
							)}

							{checkResult.suggestions?.length > 0 && (
								<div className="check-section">
									<div className="section-title">改进建议</div>
									<ul className="suggestion-list">
										{checkResult.suggestions.map((suggestion: string, idx: number) => (
											<li key={idx}>{suggestion}</li>
										))}
									</ul>
								</div>
							)}
						</div>
					</div>
				)}
			</div>
		</div>
	);
};

export default IntentEditor;
