import React, { useState, useEffect, useRef } from "react"
import { ToolUseBlock, ToolUseBlockHeader } from "../common/ToolUseBlock"
import MarkdownBlock from "../common/MarkdownBlock"

interface TodoItem {
	id?: string
	content: string
	status?: "completed" | "in_progress" | string
}

/**
 * @description
 * Editable Todo List component. Each time the todo list changes (edit, add, delete, status switch), the parent component will be notified via the onChange callback.
 * The parent component should synchronize the latest todos to the model in onChange.
 */
interface UpdateTodoListToolBlockProps {
	todos?: TodoItem[]
	content?: string
	/**
	 * Callback when todos change, be sure to implement and notify the model with the latest todos
	 * @param todos Latest todo list
	 */
	onChange: (todos: TodoItem[]) => void
	/** Whether editing is allowed (controlled externally) */
	editable?: boolean
	userEdited?: boolean
}

const STATUS_OPTIONS = [
	{ value: "", label: "Not Started", color: "var(--vscode-foreground)", border: "#bbb", bg: "transparent" },
	{
		value: "in_progress",
		label: "In Progress",
		color: "var(--vscode-charts-yellow)",
		border: "var(--vscode-charts-yellow)",
		bg: "rgba(255, 221, 51, 0.15)",
	},
	{
		value: "completed",
		label: "Completed",
		color: "var(--vscode-charts-green)",
		border: "var(--vscode-charts-green)",
		bg: "var(--vscode-charts-green)",
	},
]

const genId = () => Math.random().toString(36).slice(2, 10)

const UpdateTodoListToolBlock: React.FC<UpdateTodoListToolBlockProps> = ({
	todos = [],
	content,
	onChange,
	editable = true,
	userEdited = false,
}) => {
	const [editTodos, setEditTodos] = useState<TodoItem[]>(
		todos.length > 0 ? todos.map((todo) => ({ ...todo, id: todo.id || genId() })) : [],
	)
	const [adding, setAdding] = useState(false)
	const [newContent, setNewContent] = useState("")
	const newInputRef = useRef<HTMLInputElement>(null)
	const [deleteId, setDeleteId] = useState<string | null>(null)
	const [isEditing, setIsEditing] = useState(false)

	// Automatically exit edit mode when external editable becomes false
	useEffect(() => {
		if (!editable && isEditing) {
			setIsEditing(false)
		}
	}, [editable, isEditing])

	// Check if onChange is passed
	useEffect(() => {
		if (typeof onChange !== "function") {
			console.warn(
				"UpdateTodoListToolBlock: onChange callback not passed, cannot notify model after todo changes!",
			)
		}
		// Only check once on mount
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [])

	// Sync when external props.todos changes
	useEffect(() => {
		setEditTodos(todos.length > 0 ? todos.map((todo) => ({ ...todo, id: todo.id || genId() })) : [])
	}, [todos])

	// Auto focus on new item
	useEffect(() => {
		if (adding && newInputRef.current) {
			newInputRef.current.focus()
		}
	}, [adding])

	// Edit content
	const handleContentChange = (id: string, value: string) => {
		const newTodos = editTodos.map((todo) => (todo.id === id ? { ...todo, content: value } : todo))
		setEditTodos(newTodos)
		onChange?.(newTodos)
	}

	// Change status
	const handleStatusChange = (id: string, status: string) => {
		const newTodos = editTodos.map((todo) => (todo.id === id ? { ...todo, status } : todo))
		setEditTodos(newTodos)
		onChange?.(newTodos)
	}

	// Delete (confirmation dialog)
	const handleDelete = (id: string) => {
		setDeleteId(id)
	}
	const confirmDelete = () => {
		if (!deleteId) return
		const newTodos = editTodos.filter((todo) => todo.id !== deleteId)
		setEditTodos(newTodos)
		onChange?.(newTodos)
		setDeleteId(null)
	}
	const cancelDelete = () => setDeleteId(null)

	// Add
	const handleAdd = () => {
		if (!newContent?.trim()) return
		const newTodo: TodoItem = {
			id: genId(),
			content: newContent?.trim(),
			status: "",
		}
		const newTodos = [...editTodos, newTodo]
		setEditTodos(newTodos)
		onChange?.(newTodos)
		setNewContent("")
		setAdding(false)
	}

	// Add on Enter
	const handleNewInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
		if (e.key === "Enter") {
			handleAdd()
		} else if (e.key === "Escape") {
			setAdding(false)
			setNewContent("")
		}
	}

	if (userEdited) {
		return (
			<ToolUseBlock>
				<ToolUseBlockHeader>
					<div className="flex items-center w-full" style={{ width: "100%" }}>
						<span
							className="codicon codicon-feedback mr-1.5"
							style={{ color: "var(--vscode-charts-yellow)" }}
						/>
						<span className="font-bold mr-2" style={{ fontWeight: "bold" }}>
							User Edit
						</span>
						<div className="flex-grow" />
					</div>
				</ToolUseBlockHeader>
				<div className="overflow-x-auto max-w-full" style={{ padding: "12px 0 8px 0" }}>
					<span className="text-vscode-descriptionForeground">User Edits</span>
				</div>
			</ToolUseBlock>
		)
	}

	return (
		<>
			<ToolUseBlock>
				<ToolUseBlockHeader>
					<div className="flex items-center w-full" style={{ width: "100%" }}>
						<span
							className="codicon codicon-checklist mr-1.5"
							style={{ color: "var(--vscode-foreground)" }}
						/>
						<span className="font-bold mr-2" style={{ fontWeight: "bold" }}>
							Todo List Updated
						</span>
						<div className="flex-grow" />
						{editable && (
							<button
								onClick={() => setIsEditing(!isEditing)}
								style={{
									border: isEditing
										? "1px solid var(--vscode-button-border)"
										: "1px solid var(--vscode-button-secondaryBorder)",
									background: isEditing
										? "var(--vscode-button-background)"
										: "var(--vscode-button-secondaryBackground)",
									color: isEditing
										? "var(--vscode-button-foreground)"
										: "var(--vscode-button-secondaryForeground)",
									borderRadius: 4,
									padding: "2px 8px",
									cursor: "pointer",
									fontSize: 13,
									marginLeft: 8,
								}}>
								{isEditing ? "Done" : "Edit"}
							</button>
						)}
					</div>
				</ToolUseBlockHeader>
				<div className="overflow-x-auto max-w-full" style={{ padding: "6px 0 2px 0" }}>
					{Array.isArray(editTodos) && editTodos.length > 0 ? (
						<ul style={{ margin: 0, paddingLeft: 0, listStyle: "none" }}>
							{editTodos.map((todo, idx) => {
								let icon
								if (todo.status === "completed") {
									icon = (
										<span
											style={{
												display: "inline-block",
												width: 8,
												height: 8,
												borderRadius: "50%",
												background: "var(--vscode-charts-green)",
												marginRight: 6,
												marginTop: 7,
												flexShrink: 0,
											}}
										/>
									)
								} else if (todo.status === "in_progress") {
									icon = (
										<span
											style={{
												display: "inline-block",
												width: 8,
												height: 8,
												borderRadius: "50%",
												background: "var(--vscode-charts-yellow)",
												marginRight: 6,
												marginTop: 7,
												flexShrink: 0,
											}}
										/>
									)
								} else {
									icon = (
										<span
											style={{
												display: "inline-block",
												width: 8,
												height: 8,
												borderRadius: "50%",
												border: "1px solid var(--vscode-descriptionForeground)",
												background: "transparent",
												marginRight: 6,
												marginTop: 7,
												flexShrink: 0,
											}}
										/>
									)
								}
								return (
									<li
										key={todo.id || idx}
										style={{
											marginBottom: 2,
											display: "flex",
											alignItems: "flex-start",
											minHeight: 20,
										}}>
										{icon}
										{isEditing ? (
											<input
												type="text"
												value={todo.content}
												placeholder="Enter todo item"
												onChange={(e) => handleContentChange(todo.id!, e.target.value)}
												style={{
													flex: 1,
													minWidth: 0,
													fontWeight: 500,
													color: "var(--vscode-input-foreground)",
													background: "var(--vscode-input-background)",
													border: "none",
													outline: "none",
													fontSize: 13,
													marginRight: 6,
													padding: "1px 3px",
													borderBottom: "1px solid var(--vscode-input-border)",
												}}
												onBlur={(e) => {
													if (!e.target.value?.trim()) {
														handleDelete(todo.id!)
													}
												}}
											/>
										) : (
											<span
												style={{
													flex: 1,
													minWidth: 0,
													fontWeight: 500,
													color:
														todo.status === "completed"
															? "var(--vscode-charts-green)"
															: todo.status === "in_progress"
																? "var(--vscode-charts-yellow)"
																: "var(--vscode-foreground)",
													fontSize: 13,
													marginRight: 6,
													padding: "1px 3px",
													lineHeight: "1.4",
												}}>
												{todo.content}
											</span>
										)}
										{isEditing && (
											<select
												value={todo.status || ""}
												onChange={(e) => handleStatusChange(todo.id!, e.target.value)}
												style={{
													marginRight: 6,
													borderRadius: 4,
													border: "1px solid var(--vscode-input-border)",
													background: "var(--vscode-input-background)",
													color: "var(--vscode-input-foreground)",
													fontSize: 12,
													padding: "1px 4px",
												}}>
												{STATUS_OPTIONS.map((opt) => (
													<option key={opt.value} value={opt.value}>
														{opt.label}
													</option>
												))}
											</select>
										)}
										{isEditing && (
											<button
												onClick={() => handleDelete(todo.id!)}
												style={{
													border: "none",
													background: "transparent",
													color: "#f14c4c",
													cursor: "pointer",
													fontSize: 14,
													marginLeft: 2,
													padding: 0,
													lineHeight: 1,
												}}
												title="Remove">
												×
											</button>
										)}
									</li>
								)
							})}
							{adding ? (
								<li style={{ marginTop: 2, display: "flex", alignItems: "center" }}>
									<span style={{ width: 14, marginRight: 6 }} />
									<input
										ref={newInputRef}
										type="text"
										value={newContent}
										placeholder="Enter todo item, press Enter to add"
										onChange={(e) => setNewContent(e.target.value)}
										onKeyDown={handleNewInputKeyDown}
										style={{
											flex: 1,
											minWidth: 0,
											fontWeight: 500,
											color: "var(--vscode-foreground)",
											background: "transparent",
											border: "none",
											outline: "none",
											fontSize: 13,
											marginRight: 6,
											padding: "1px 3px",
											borderBottom: "1px solid #eee",
										}}
									/>
									<button
										onClick={handleAdd}
										disabled={!newContent?.trim()}
										style={{
											border: "1px solid var(--vscode-button-border)",
											background: "var(--vscode-button-background)",
											color: "var(--vscode-button-foreground)",
											borderRadius: 4,
											padding: "1px 7px",
											cursor: newContent?.trim() ? "pointer" : "not-allowed",
											fontSize: 12,
											marginRight: 4,
										}}>
										Add
									</button>
									<button
										onClick={() => {
											setAdding(false)
											setNewContent("")
										}}
										style={{
											border: "1px solid var(--vscode-button-secondaryBorder)",
											background: "var(--vscode-button-secondaryBackground)",
											color: "var(--vscode-button-secondaryForeground)",
											borderRadius: 4,
											padding: "1px 7px",
											cursor: "pointer",
											fontSize: 12,
										}}>
										Cancel
									</button>
								</li>
							) : (
								<li style={{ marginTop: 2 }}>
									{isEditing && (
										<button
											onClick={() => setAdding(true)}
											style={{
												border: "1px dashed var(--vscode-button-secondaryBorder)",
												background: "var(--vscode-button-secondaryBackground)",
												color: "var(--vscode-button-secondaryForeground)",
												borderRadius: 4,
												padding: "1px 8px",
												cursor: "pointer",
												fontSize: 12,
											}}>
											+ Add Todo
										</button>
									)}
								</li>
							)}
						</ul>
					) : (
						<MarkdownBlock markdown={content} />
					)}
				</div>
				{/* Delete confirmation dialog */}
				{deleteId && (
					<div
						style={{
							position: "fixed",
							left: 0,
							top: 0,
							right: 0,
							bottom: 0,
							background: "rgba(0,0,0,0.15)",
							zIndex: 9999,
							display: "flex",
							alignItems: "center",
							justifyContent: "center",
						}}
						onClick={cancelDelete}>
						<div
							style={{
								background: "#fff",
								borderRadius: 8,
								boxShadow: "0 2px 16px rgba(0,0,0,0.15)",
								padding: "16px 20px",
								minWidth: 200,
								zIndex: 10000,
							}}
							onClick={(e) => e.stopPropagation()}>
							<div style={{ marginBottom: 12, fontSize: 14, color: "#333" }}>
								Are you sure you want to delete this todo item?
							</div>
							<div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
								<button
									onClick={cancelDelete}
									style={{
										border: "1px solid #bbb",
										background: "transparent",
										color: "#888",
										borderRadius: 4,
										padding: "2px 10px",
										cursor: "pointer",
										fontSize: 12,
									}}>
									Cancel
								</button>
								<button
									onClick={confirmDelete}
									style={{
										border: "1px solid #f14c4c",
										background: "#f14c4c",
										color: "#fff",
										borderRadius: 4,
										padding: "2px 10px",
										cursor: "pointer",
										fontSize: 12,
									}}>
									Delete
								</button>
							</div>
						</div>
					</div>
				)}
			</ToolUseBlock>
		</>
	)
}

export default UpdateTodoListToolBlock
