import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
	Card,
	CardContent,
	CardFooter,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";
import { Textarea } from "@/components/ui/textarea";
import { useToast } from "@/hooks/use-toast";
import {
	Edit,
	MessageCircle,
	MessageSquare,
	ThumbsUp,
	Trash,
	X,
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import type { AnnotationWithUser } from "../../../../shared/schema";

interface AnnotationSystemProps {
	workId: string;
	selectedLineNumber: number | null;
	onClose: () => void;
	translationId?: string;
}

export function AnnotationSystem({
	workId,
	selectedLineNumber,
	onClose,
	translationId,
}: AnnotationSystemProps) {
	const { toast } = useToast();
	const [annotations, setAnnotations] = useState<AnnotationWithUser[]>([]);
	const [isLoading, setIsLoading] = useState(true);
	const [newAnnotation, setNewAnnotation] = useState("");
	const [isSubmitting, setIsSubmitting] = useState(false);
	const [editingAnnotationId, setEditingAnnotationId] = useState<string | null>(
		null,
	);
	const [editText, setEditText] = useState("");

	const annotationRef = useRef<HTMLDivElement>(null);

	// Mock user data - in a real app this would come from auth
	const currentUser = {
		id: "1",
		name: "Anonymous",
		avatar: null,
	};

	// Fetch annotations for the selected line
	useEffect(() => {
		if (!selectedLineNumber) return;

		setIsLoading(true);

		// Simulate API call to get annotations for the selected line
		setTimeout(() => {
			// These would be fetched from the API in a real app
			const mockAnnotations: AnnotationWithUser[] = [
				{
					id: "1" as const,
					workId: workId,
					translationId: translationId,
					lineNumber: selectedLineNumber,
					userId: "2" as const,
					user: {
						name: "Literary Scholar",
						avatar: undefined,
					},
					likes: 5,
					liked: false,
					content:
						"This line demonstrates the poet's use of alliteration, creating a rhythmic pattern that emphasizes the emotional tone.",
					type: "analysis" as const,
					isOfficial: false,
					createdAt: new Date(Date.now() - 1000000).toISOString(),
				},
				{
					id: "2" as const,
					workId: workId,
					translationId: translationId,
					lineNumber: selectedLineNumber,
					userId: "3" as const,
					user: {
						name: "Translator",
						avatar: undefined,
					},
					likes: 3,
					liked: false,
					content:
						"The original meaning in Russian contains a wordplay that is difficult to capture in English. A more literal translation might read as...",
					type: "translation" as const,
					isOfficial: false,
					createdAt: new Date(Date.now() - 5000000).toISOString(),
				},
			];

			setAnnotations(mockAnnotations);
			setIsLoading(false);
		}, 600);
	}, [workId, selectedLineNumber, translationId]);

	// Submit new annotation
	const handleSubmitAnnotation = async () => {
		if (!newAnnotation.trim() || !selectedLineNumber) return;

		setIsSubmitting(true);

		try {
			// In a real app, this would be an API call
			// Mock API response
			const newAnnotationObj: AnnotationWithUser = {
				id: Date.now().toString(),
				workId,
				translationId,
				lineNumber: selectedLineNumber,
				userId: currentUser.id.toString(),
				user: {
					name: currentUser.name,
					avatar: currentUser.avatar || undefined,
				},
				content: newAnnotation,
				type: "comment",
				isOfficial: false,
				createdAt: new Date().toISOString(),
				likes: 0,
				liked: false,
			};

			// Optimistically update UI
			setAnnotations((prev) => [newAnnotationObj, ...prev]);
			setNewAnnotation("");

			toast({
				description: "Annotation added successfully",
			});

			// In a real app, this would invalidate the query cache
			// queryClient.invalidateQueries({ queryKey: [`/api/works/${workId}/annotations/${selectedLineNumber}`] });
		} catch (_error) {
			toast({
				title: "Error",
				description: "Failed to add annotation",
				variant: "destructive",
			});
		} finally {
			setIsSubmitting(false);
		}
	};

	// Like an annotation
	const handleLikeAnnotation = async (annotationId: string) => {
		try {
			// Optimistically update UI
			setAnnotations((prev) =>
				prev.map((anno) =>
					anno.id === annotationId
						? {
								...anno,
								liked: !anno.liked,
								likes: anno.liked ? (anno.likes || 0) - 1 : (anno.likes || 0) + 1,
							}
						: anno,
				),
			);

			// In a real app, this would be an API call
			// await apiRequest('POST', `/api/annotations/${annotationId}/like`, { userId: currentUser.id });
		} catch (_error) {
			// Revert optimistic update if there's an error
			setAnnotations((prev) => [...prev]);
			toast({
				title: "Error",
				description: "Failed to update like",
				variant: "destructive",
			});
		}
	};

	// Delete annotation
	const handleDeleteAnnotation = async (annotationId: string) => {
		try {
			// Optimistically update UI
			const filteredAnnotations = annotations.filter(
				(anno) => anno.id !== annotationId,
			);
			setAnnotations(filteredAnnotations);

			// In a real app, this would be an API call
			// await apiRequest('DELETE', `/api/annotations/${annotationId}`);

			toast({
				description: "Annotation deleted",
			});
		} catch (_error) {
			// Revert optimistic update if there's an error
			toast({
				title: "Error",
				description: "Failed to delete annotation",
				variant: "destructive",
			});
		}
	};

	// Start editing an annotation
	const handleStartEdit = (annotation: AnnotationWithUser) => {
		setEditingAnnotationId(annotation.id);
		setEditText(annotation.content);
	};

	// Save edited annotation
	const handleSaveEdit = async (annotationId: string) => {
		if (!editText.trim()) return;

		try {
			// Optimistically update UI
			setAnnotations((prev) =>
				prev.map((anno) =>
					anno.id === annotationId ? { ...anno, content: editText } : anno,
				),
			);

			// Reset edit state
			setEditingAnnotationId(null);
			setEditText("");

			// In a real app, this would be an API call
			// await apiRequest('PATCH', `/api/annotations/${annotationId}`, { content: editText });

			toast({
				description: "Annotation updated",
			});
		} catch (_error) {
			toast({
				title: "Error",
				description: "Failed to update annotation",
				variant: "destructive",
			});
		}
	};

	// Cancel editing
	const handleCancelEdit = () => {
		setEditingAnnotationId(null);
		setEditText("");
	};

	// If no line is selected, don't render anything
	if (!selectedLineNumber) return null;

	return (
		<div
			ref={annotationRef}
			className="annotation-panel bg-cream dark:bg-dark-surface border-l border-sage/20 dark:border-sage/10 w-80 lg:w-96 fixed top-0 right-0 bottom-0 z-50 overflow-y-auto transition-transform shadow-xl"
		>
			<div className="sticky top-0 z-10 bg-cream dark:bg-dark-surface border-b border-sage/20 dark:border-sage/10 px-4 py-3 flex justify-between items-center">
				<div className="flex items-center gap-2">
					<MessageSquare className="h-5 w-5 text-russet" />
					<h3 className="font-medium text-navy dark:text-cream">
						Line {selectedLineNumber} Annotations
					</h3>
				</div>
				<Button variant="ghost" size="icon" onClick={onClose}>
					<X className="h-5 w-5" />
					<span className="sr-only">Close</span>
				</Button>
			</div>

			<div className="p-4">
				{/* New annotation form */}
				<div className="mb-6">
					<Textarea
						placeholder="Add your annotation to this line..."
						className="min-h-24 resize-y"
						value={newAnnotation}
						onChange={(e) => setNewAnnotation(e.target.value)}
					/>
					<div className="flex justify-end mt-2">
						<Button
							onClick={handleSubmitAnnotation}
							disabled={isSubmitting || !newAnnotation.trim()}
							className="bg-russet hover:bg-russet/90 text-white"
						>
							{isSubmitting ? "Submitting..." : "Add Annotation"}
						</Button>
					</div>
				</div>

				{/* Annotations list */}
				<div className="space-y-4">
					{isLoading ? (
						<div className="text-center py-8">
							<div className="loader"></div>
							<p className="text-navy/70 dark:text-cream/70 mt-2">
								Loading annotations...
							</p>
						</div>
					) : annotations.length === 0 ? (
						<div className="text-center py-8">
							<MessageCircle className="h-12 w-12 mx-auto text-navy/30 dark:text-cream/30" />
							<p className="text-navy/70 dark:text-cream/70 mt-2">
								No annotations yet
							</p>
							<p className="text-sm text-navy/50 dark:text-cream/50">
								Be the first to annotate this line
							</p>
						</div>
					) : (
						annotations.map((annotation) => (
							<Card
								key={annotation.id}
								className="border-sage/20 dark:border-sage/10"
							>
								<CardHeader className="pb-2">
									<div className="flex justify-between items-start">
										<div className="flex items-center gap-2">
											<Avatar className="h-8 w-8">
												<AvatarImage
													src={annotation.user.avatar || ""}
													alt={annotation.user.name}
												/>
												<AvatarFallback className="text-xs bg-navy/10 dark:bg-navy/20 text-navy dark:text-cream">
													{annotation.user.name.charAt(0).toUpperCase()}
												</AvatarFallback>
											</Avatar>
											<div>
												<CardTitle className="text-sm font-medium text-navy dark:text-cream">
													{annotation.user.name}
												</CardTitle>
												<p className="text-xs text-navy/60 dark:text-cream/60">
													{new Date(annotation.createdAt).toLocaleDateString()}
												</p>
											</div>
										</div>

										{/* Edit/Delete buttons for user's own annotations */}
										{annotation.userId === currentUser.id.toString() && (
											<div className="flex items-center gap-1">
												<Button
													variant="ghost"
													size="icon"
													className="h-8 w-8"
													onClick={() => handleStartEdit(annotation)}
												>
													<Edit className="h-4 w-4" />
													<span className="sr-only">Edit</span>
												</Button>
												<Button
													variant="ghost"
													size="icon"
													className="h-8 w-8 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
													onClick={() => handleDeleteAnnotation(annotation.id)}
												>
													<Trash className="h-4 w-4" />
													<span className="sr-only">Delete</span>
												</Button>
											</div>
										)}
									</div>
								</CardHeader>

								<CardContent className="pt-2">
									{editingAnnotationId === annotation.id ? (
										<div>
											<Textarea
												value={editText}
												onChange={(e) => setEditText(e.target.value)}
												className="min-h-24 resize-y mb-2"
											/>
											<div className="flex justify-end gap-2">
												<Button
													variant="outline"
													size="sm"
													onClick={handleCancelEdit}
												>
													Cancel
												</Button>
												<Button
													size="sm"
													onClick={() => handleSaveEdit(annotation.id)}
													disabled={!editText.trim()}
												>
													Save
												</Button>
											</div>
										</div>
									) : (
										<p className="text-sm text-navy/90 dark:text-cream/90 whitespace-pre-wrap">
											{annotation.content}
										</p>
									)}
								</CardContent>

								<CardFooter className="pt-2 flex justify-between items-center">
									<Button
										variant="ghost"
										size="sm"
										className={`flex items-center gap-1 text-xs ${
											annotation.liked
												? "text-russet"
												: "text-navy/70 dark:text-cream/70"
										}`}
										onClick={() => handleLikeAnnotation(annotation.id)}
									>
										<ThumbsUp
											className={`h-4 w-4 ${annotation.liked ? "fill-russet" : ""}`}
										/>
										<span>{annotation.likes}</span>
									</Button>

									<Button
										variant="ghost"
										size="sm"
										className="text-xs text-navy/70 dark:text-cream/70"
									>
										<MessageCircle className="h-4 w-4 mr-1" />
										<span>Reply</span>
									</Button>
								</CardFooter>
							</Card>
						))
					)}
				</div>
			</div>
		</div>
	);
}
