"use client";

import {
	closestCenter,
	DndContext,
	type DragEndEvent,
	DragOverlay,
	type DragStartEvent,
	KeyboardSensor,
	PointerSensor,
	useSensor,
	useSensors,
} from "@dnd-kit/core";
import {
	arrayMove,
	SortableContext,
	sortableKeyboardCoordinates,
	verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import {
	Button,
	Card,
	CardContent,
	CardHeader,
	Input,
	Textarea,
} from "@mdxui/primitives";
import { cn } from "@mdxui/primitives/lib/utils";
import { Plus, Settings } from "lucide-react";
import * as React from "react";
import { QuestionItem } from "./question-item";
import { QuestionTypeSelector } from "./question-type-selector";
import type {
	QuestionType,
	Survey,
	SurveyBuilderProps,
	SurveyQuestion,
} from "./types";

export function SurveyBuilder({
	survey: initialSurvey,
	onChange,
	onQuestionSelect,
	readOnly = false,
	className,
}: SurveyBuilderProps) {
	const [survey, setSurvey] = React.useState<Survey>(
		initialSurvey || {
			id: crypto.randomUUID(),
			title: "Untitled Survey",
			description: "",
			questions: [],
			settings: {
				showProgressBar: true,
				allowBack: true,
				randomizeQuestions: false,
			},
		},
	);
	const [activeQuestion, setActiveQuestion] =
		React.useState<SurveyQuestion | null>(null);

	React.useEffect(() => {
		if (initialSurvey) {
			setSurvey(initialSurvey);
		}
	}, [initialSurvey]);

	React.useEffect(() => {
		onChange?.(survey);
	}, [survey, onChange]);

	const sensors = useSensors(
		useSensor(PointerSensor, {
			activationConstraint: {
				distance: 8,
			},
		}),
		useSensor(KeyboardSensor, {
			coordinateGetter: sortableKeyboardCoordinates,
		}),
	);

	const handleDragStart = (event: DragStartEvent) => {
		const { active } = event;
		const question = survey.questions.find((q) => q.id === active.id);
		if (question) {
			setActiveQuestion(question);
		}
	};

	const handleDragEnd = (event: DragEndEvent) => {
		const { active, over } = event;
		setActiveQuestion(null);

		if (!over || active.id === over.id) return;

		setSurvey((prev) => {
			const oldIndex = prev.questions.findIndex((q) => q.id === active.id);
			const newIndex = prev.questions.findIndex((q) => q.id === over.id);

			return {
				...prev,
				questions: arrayMove(prev.questions, oldIndex, newIndex),
			};
		});
	};

	const handleAddQuestion = (type: QuestionType) => {
		const newQuestion: SurveyQuestion = {
			id: crypto.randomUUID(),
			type,
			title: "Untitled Question",
			description: "",
			required: false,
			...(type === "single-choice" || type === "multiple-choice"
				? {
						options: [
							{ id: crypto.randomUUID(), label: "Option 1", value: "option-1" },
							{ id: crypto.randomUUID(), label: "Option 2", value: "option-2" },
						],
					}
				: {}),
		};

		setSurvey((prev) => ({
			...prev,
			questions: [...prev.questions, newQuestion],
		}));
	};

	const handleUpdateQuestion = (
		questionId: string,
		updates: Partial<SurveyQuestion>,
	) => {
		setSurvey((prev) => ({
			...prev,
			questions: prev.questions.map((q) =>
				q.id === questionId ? { ...q, ...updates } : q,
			),
		}));
	};

	const handleDeleteQuestion = (questionId: string) => {
		setSurvey((prev) => ({
			...prev,
			questions: prev.questions.filter((q) => q.id !== questionId),
		}));
	};

	const handleDuplicateQuestion = (questionId: string) => {
		const question = survey.questions.find((q) => q.id === questionId);
		if (!question) return;

		const duplicated: SurveyQuestion = {
			...question,
			id: crypto.randomUUID(),
			title: `${question.title} (Copy)`,
			options: question.options?.map((opt) => ({
				...opt,
				id: crypto.randomUUID(),
			})),
		};

		setSurvey((prev) => ({
			...prev,
			questions: [...prev.questions, duplicated],
		}));
	};

	const handleTitleChange = (title: string) => {
		setSurvey((prev) => ({ ...prev, title }));
	};

	const handleDescriptionChange = (description: string) => {
		setSurvey((prev) => ({ ...prev, description }));
	};

	return (
		<div className={cn("space-y-6", className)}>
			<Card>
				<CardHeader>
					<div className="flex items-start justify-between">
						<div className="flex-1 space-y-2">
							<Input
								value={survey.title}
								onChange={(e) => handleTitleChange(e.target.value)}
								placeholder="Survey Title"
								className="text-2xl font-bold"
								disabled={readOnly}
							/>
							<Textarea
								value={survey.description || ""}
								onChange={(e) => handleDescriptionChange(e.target.value)}
								placeholder="Survey Description (optional)"
								className="resize-none"
								rows={2}
								disabled={readOnly}
							/>
						</div>
						<Button variant="ghost" size="icon-sm">
							<Settings className="size-4" />
						</Button>
					</div>
				</CardHeader>
			</Card>

			<DndContext
				sensors={sensors}
				collisionDetection={closestCenter}
				onDragStart={handleDragStart}
				onDragEnd={handleDragEnd}
			>
				<div className="space-y-4">
					<SortableContext
						items={survey.questions.map((q) => q.id)}
						strategy={verticalListSortingStrategy}
					>
						{survey.questions.map((question, index) => (
							<QuestionItem
								key={question.id}
								question={question}
								index={index}
								onUpdate={handleUpdateQuestion}
								onDelete={handleDeleteQuestion}
								onDuplicate={handleDuplicateQuestion}
								onSelect={() => onQuestionSelect?.(question)}
								readOnly={readOnly}
							/>
						))}
					</SortableContext>

					{survey.questions.length === 0 && (
						<Card>
							<CardContent className="flex h-32 items-center justify-center">
								<p className="text-sm text-muted-foreground">
									No questions yet. Add your first question below.
								</p>
							</CardContent>
						</Card>
					)}
				</div>

				<DragOverlay>
					{activeQuestion && (
						<Card className="opacity-50">
							<CardContent className="p-4">
								<p className="font-medium">{activeQuestion.title}</p>
							</CardContent>
						</Card>
					)}
				</DragOverlay>
			</DndContext>

			{!readOnly && (
				<QuestionTypeSelector onSelect={handleAddQuestion}>
					<Button variant="outline" className="w-full">
						<Plus className="mr-2 size-4" />
						Add Question
					</Button>
				</QuestionTypeSelector>
			)}
		</div>
	);
}
