"use client";

import { formatDistanceToNow } from "date-fns";
import { fr } from "date-fns/locale";
import { Heart, MoreHorizontal, Send, Trash2 } from "lucide-react";
import * as React from "react";
import { toast } from "sonner";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
	DropdownMenu,
	DropdownMenuContent,
	DropdownMenuItem,
	DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import { useAuth } from "@/providers/auth-provider";
import { useSocket } from "@/providers/socket-provider";
import { type Comment, CommentService } from "@/services/comment.service";

interface CommentSectionProps {
	contentId: string;
}

export function CommentSection({ contentId }: CommentSectionProps) {
	const { user, isAuthenticated } = useAuth();
	const { socket } = useSocket();
	const [comments, setComments] = React.useState<Comment[]>([]);
	const [newComment, setNewComment] = React.useState("");
	const [replyingTo, setReplyingTo] = React.useState<Comment | null>(null);
	const [isSubmitting, setIsSubmitting] = React.useState(false);
	const [isLoading, setIsLoading] = React.useState(true);

	const fetchComments = React.useCallback(async () => {
		try {
			const data = await CommentService.getByContentId(contentId);
			setComments(data);
		} catch (_error) {
			toast.error("Impossible de charger les commentaires");
		} finally {
			setIsLoading(false);
		}
	}, [contentId]);

	React.useEffect(() => {
		fetchComments();
	}, [fetchComments]);

	// Gestion du WebSocket
	React.useEffect(() => {
		if (socket) {
			socket.emit("join_content", contentId);

			socket.on("new_comment", (comment: Comment) => {
				setComments((prev) => {
					// Éviter les doublons si l'auteur reçoit son propre commentaire via WS
					if (prev.some((c) => c.id === comment.id)) return prev;
					return [comment, ...prev];
				});
			});

			return () => {
				socket.emit("leave_content", contentId);
				socket.off("new_comment");
			};
		}
	}, [socket, contentId]);

	const handleSubmit = async (e: React.FormEvent) => {
		e.preventDefault();
		if (!newComment.trim() || isSubmitting) return;

		setIsSubmitting(true);
		try {
			const comment = await CommentService.create(
				contentId,
				newComment.trim(),
				replyingTo?.id,
			);
			setComments((prev) => [comment, ...prev]);
			setNewComment("");
			setReplyingTo(null);
			toast.success("Commentaire publié !");
		} catch (_error) {
			toast.error("Erreur lors de la publication du commentaire");
		} finally {
			setIsSubmitting(false);
		}
	};

	const handleDelete = async (commentId: string) => {
		try {
			await CommentService.remove(commentId);
			setComments((prev) => prev.filter((c) => c.id !== commentId));
			toast.success("Commentaire supprimé");
		} catch (_error) {
			toast.error("Erreur lors de la suppression");
		}
	};

	const handleLike = async (comment: Comment) => {
		if (!isAuthenticated) {
			toast.error("Vous devez être connecté pour liker");
			return;
		}

		try {
			if (comment.isLiked) {
				await CommentService.unlike(comment.id);
				setComments((prev) =>
					prev.map((c) =>
						c.id === comment.id
							? { ...c, isLiked: false, likesCount: c.likesCount - 1 }
							: c,
					),
				);
			} else {
				await CommentService.like(comment.id);
				setComments((prev) =>
					prev.map((c) =>
						c.id === comment.id
							? { ...c, isLiked: true, likesCount: c.likesCount + 1 }
							: c,
					),
				);
			}
		} catch (_error) {
			toast.error("Une erreur est survenue");
		}
	};

	// Organiser les commentaires : Parents d'abord
	const rootComments = comments.filter((c) => !c.parentId);

	const renderComment = (comment: Comment, depth = 0) => {
		const replies = comments.filter((c) => c.parentId === comment.id);

		return (
			<div key={comment.id} className={cn("space-y-4", depth > 0 && "ml-10")}>
				<div className="flex gap-3">
					<Avatar className="h-8 w-8 shrink-0">
						<AvatarImage src={comment.user.avatarUrl} />
						<AvatarFallback>{comment.user.username[0].toUpperCase()}</AvatarFallback>
					</Avatar>
					<div className="flex-1 space-y-1">
						<div className="flex items-center justify-between">
							<div className="flex items-center gap-2">
								<span className="text-sm font-bold">
									{comment.user.displayName || comment.user.username}
								</span>
								<span className="text-xs text-muted-foreground">
									{formatDistanceToNow(new Date(comment.createdAt), {
										addSuffix: true,
										locale: fr,
									})}
								</span>
							</div>
							<div className="flex items-center gap-1">
								<Button
									variant="ghost"
									size="icon"
									className={cn(
										"h-8 w-8",
										comment.isLiked && "text-red-500 hover:text-red-600",
									)}
									onClick={() => handleLike(comment)}
								>
									<Heart className={cn("h-4 w-4", comment.isLiked && "fill-current")} />
								</Button>
								{(user?.uuid === comment.user.uuid ||
									user?.role === "admin" ||
									user?.role === "moderator") && (
									<DropdownMenu>
										<DropdownMenuTrigger asChild>
											<Button variant="ghost" size="icon" className="h-8 w-8">
												<MoreHorizontal className="h-4 w-4" />
											</Button>
										</DropdownMenuTrigger>
										<DropdownMenuContent align="end">
											<DropdownMenuItem
												onClick={() => handleDelete(comment.id)}
												className="text-destructive"
											>
												<Trash2 className="h-4 w-4 mr-2" />
												Supprimer
											</DropdownMenuItem>
										</DropdownMenuContent>
									</DropdownMenu>
								)}
							</div>
						</div>
						<p className="text-sm leading-relaxed whitespace-pre-wrap">
							{comment.text}
						</p>
						<div className="flex items-center gap-4 pt-1">
							{comment.likesCount > 0 && (
								<span className="text-xs font-semibold text-muted-foreground">
									{comment.likesCount} like{comment.likesCount > 1 ? "s" : ""}
								</span>
							)}
							{isAuthenticated && depth < 1 && (
								<Button
									variant="ghost"
									size="sm"
									className="h-auto p-0 text-xs font-semibold text-muted-foreground hover:bg-transparent hover:text-foreground"
									onClick={() => {
										setReplyingTo(comment);
										setNewComment(`@${comment.user.username} `);
										document.querySelector("textarea")?.focus();
									}}
								>
									Répondre
								</Button>
							)}
						</div>
					</div>
				</div>
				{replies.length > 0 && (
					<div className="space-y-4 pt-2">
						{replies.map((reply) => renderComment(reply, depth + 1))}
					</div>
				)}
			</div>
		);
	};

	return (
		<div className="space-y-6 mt-8">
			<div className="flex items-center justify-between">
				<h3 className="font-bold text-lg">Commentaires ({comments.length})</h3>
			</div>

			{isAuthenticated ? (
				<div className="space-y-2">
					{replyingTo && (
						<div className="flex items-center justify-between bg-zinc-100 dark:bg-zinc-800 px-3 py-1.5 rounded-lg text-xs">
							<span className="text-muted-foreground">
								En réponse à{" "}
								<span className="font-bold">@{replyingTo.user.username}</span>
							</span>
							<Button
								variant="ghost"
								size="icon"
								className="h-4 w-4"
								onClick={() => {
									setReplyingTo(null);
									setNewComment("");
								}}
							>
								<Trash2 className="h-3 w-3" />
							</Button>
						</div>
					)}
					<form onSubmit={handleSubmit} className="flex gap-3">
						<Avatar className="h-8 w-8 shrink-0">
							<AvatarImage src={user?.avatarUrl} />
							<AvatarFallback>{user?.username[0].toUpperCase()}</AvatarFallback>
						</Avatar>
						<div className="flex-1 space-y-2">
							<Textarea
								placeholder={
									replyingTo ? "Ajouter une réponse..." : "Ajouter un commentaire..."
								}
								value={newComment}
								onChange={(e) => setNewComment(e.target.value)}
								className="min-h-[80px] resize-none"
							/>
							<div className="flex justify-end gap-2">
								{replyingTo && (
									<Button
										type="button"
										variant="ghost"
										size="sm"
										onClick={() => {
											setReplyingTo(null);
											setNewComment("");
										}}
									>
										Annuler
									</Button>
								)}
								<Button
									type="submit"
									size="sm"
									disabled={!newComment.trim() || isSubmitting}
								>
									{isSubmitting ? "Envoi..." : replyingTo ? "Répondre" : "Publier"}
									<Send className="ml-2 h-4 w-4" />
								</Button>
							</div>
						</div>
					</form>
				</div>
			) : (
				<div className="bg-zinc-100 dark:bg-zinc-800 p-4 rounded-xl text-center text-sm">
					Connectez-vous pour laisser un commentaire.
				</div>
			)}

			<div className="space-y-6">
				{isLoading ? (
					<div className="text-center text-muted-foreground py-4">Chargement...</div>
				) : rootComments.length === 0 ? (
					<div className="text-center text-muted-foreground py-4">
						Aucun commentaire pour le moment. Soyez le premier !
					</div>
				) : (
					rootComments.map((comment) => renderComment(comment))
				)}
			</div>
		</div>
	);
}
