import { zodResolver } from "@hookform/resolvers/zod";
import { AlertCircle, BookOpen, BookText, Trash2 } from "lucide-react";
import { useState } from "react";
import { useForm } from "react-hook-form";
import * as z from "zod";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";
import { FileUploader } from "@/components/ui/file-uploader";
import {
	Form,
	FormControl,
	FormDescription,
	FormField,
	FormItem,
	FormLabel,
	FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { RichTextEditor } from "@/components/ui/rich-text-editor";
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import TagInput, { type TagItem } from "@/components/ui/tag-input";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import type { Author } from "./work-header";

/**
 * Work Editor component for creating and editing literary works
 *
 * @example
 * ```tsx
 * <WorkEditor
 *   work={existingWork}
 *   authors={authors}
 *   languages={languages}
 *   genres={genres}
 *   onSave={handleSave}
 *   onCancel={handleCancel}
 * />
 * ```
 */

// Define the schema for the work form
const workFormSchema = z.object({
	title: z
		.string()
		.min(2, "Title must be at least 2 characters")
		.max(200, "Title must be less than 200 characters"),
	subtitle: z.string().optional(),
	authorId: z.string().min(1, "Author is required"),
	description: z.string().optional(),
	publicationYear: z
		.string()
		.refine((val) => !val || /^\d{4}$/.test(val), {
			message: "Year must be a 4-digit number",
		})
		.transform((val) => (val ? parseInt(val) : undefined))
		.optional(),
	language: z.string().min(1, "Language is required"),
	content: z.string().min(10, "Content is required").optional(),
	status: z.enum(["draft", "review", "published", "archived"]).default("draft"),
});

// Infer the form values type from the schema
type WorkFormValues = z.infer<typeof workFormSchema>;

export interface Work {
	id?: number | string;
	title: string;
	subtitle?: string;
	authorId: number | string;
	description?: string;
	publicationYear?: number;
	language: string;
	content?: string;
	status?: "draft" | "review" | "published" | "archived";
	genres?: string[];
	coverImage?: string;
	slug?: string;
}

export interface WorkEditorProps {
	/**
	 * Work data for editing (optional, if creating new)
	 */
	work?: Partial<Work>;
	/**
	 * Available authors
	 */
	authors: Author[];
	/**
	 * Available languages
	 */
	languages: { code: string; name: string }[];
	/**
	 * Available genres for selection
	 */
	genres?: { id: string | number; name: string }[];
	/**
	 * Whether the form is in loading state
	 */
	isLoading?: boolean;
	/**
	 * Whether the form is in read-only mode
	 */
	readOnly?: boolean;
	/**
	 * Whether to show translation fields
	 */
	showTranslationFields?: boolean;
	/**
	 * Whether to show a preview tab
	 */
	showPreview?: boolean;
	/**
	 * Callback when saving the work
	 */
	onSave?: (data: Work) => void;
	/**
	 * Callback when publication status changes
	 */
	onStatusChange?: (status: string) => void;
	/**
	 * Callback when canceling
	 */
	onCancel?: () => void;
	/**
	 * Callback for deleting a work
	 */
	onDelete?: (id: number | string) => void;
	/**
	 * CSS class for the container
	 */
	className?: string;
}

export function WorkEditor({
	work,
	authors = [],
	languages = [],
	genres = [],
	isLoading = false,
	readOnly = false,
	showTranslationFields = false,
	showPreview = true,
	onSave,
	onStatusChange,
	onCancel,
	onDelete,
	className,
}: WorkEditorProps) {
	const [activeTab, setActiveTab] = useState("basic");
	const [coverImage, setCoverImage] = useState<File | null>(null);
	const [coverPreview, setCoverPreview] = useState<string | undefined>(
		work?.coverImage,
	);
	const [selectedGenres, setSelectedGenres] = useState<TagItem[]>(
		work?.genres?.map((genre) => ({ value: genre, label: genre })) || [],
	);
	const [previewMode, setPreviewMode] = useState(false);
	const [workContent, setWorkContent] = useState(work?.content || "");

	// Initialize form with default values
	const form = useForm({
		resolver: zodResolver(workFormSchema),
		defaultValues: {
			title: work?.title || "",
			subtitle: work?.subtitle || "",
			authorId: work?.authorId?.toString() || "",
			description: work?.description || "",
			publicationYear: work?.publicationYear?.toString() || "",
			language: work?.language || "",
			content: work?.content || "",
			status: work?.status || "draft",
		},
		mode: "onChange",
	}) as any;

	// Watch values for preview
	const watchedValues = form.watch();

	// Handle form submission
	const onSubmit = (formData: any) => {
		if (onSave) {
			// Convert to our strongly typed form values
			const data = formData as WorkFormValues;

			// Prepare the work data
			const workData: Work = {
				title: data.title,
				language: data.language,
				authorId: data.authorId,
				subtitle: data.subtitle,
				description: data.description,
				// Convert publication year to number if available
				publicationYear: data.publicationYear
					? Number(data.publicationYear)
					: undefined,
				content: data.content,
				status: data.status,
				genres: selectedGenres.map((tag) => tag.value),
			};

			// If there's a new cover image, we'd typically upload it here
			// and add the URL to workData
			if (coverImage) {
				// In a real app, you'd upload the file and get a URL
				// workData.coverImage = uploadedUrl;
			} else if (coverPreview) {
				workData.coverImage = coverPreview;
			}

			// Add content if we have it
			if (workContent) {
				workData.content = workContent;
			}

			// If editing, include the ID
			if (work?.id) {
				workData.id = work.id;
			}

			onSave(workData);
		}
	};

	// Handle status change
	const handleStatusChange = (status: string) => {
		form.setValue("status", status as any);
		onStatusChange?.(status);
	};

	// Handle file selection for cover image
	const handleCoverImageSelect = (files: File[]) => {
		if (files.length > 0) {
			setCoverImage(files[0]);
			setCoverPreview(URL.createObjectURL(files[0]));
		}
	};

	return (
		<div className={cn("space-y-6", className)}>
			{/* Form title */}
			<div className="flex justify-between items-center">
				<div>
					<h1 className="text-2xl font-bold tracking-tight">
						{work?.id ? "Edit Work" : "Create New Work"}
					</h1>
					<p className="text-muted-foreground">
						{work?.id
							? "Update the details of your literary work"
							: "Enter the details of your new literary work"}
					</p>
				</div>

				{/* Status selection for existing works */}
				{work?.id && (
					<Select
						value={form.getValues("status")}
						onValueChange={handleStatusChange}
						disabled={isLoading || readOnly}
					>
						<SelectTrigger className="w-[180px]">
							<SelectValue placeholder="Select status" />
						</SelectTrigger>
						<SelectContent>
							<SelectItem value="draft">Draft</SelectItem>
							<SelectItem value="review">Under Review</SelectItem>
							<SelectItem value="published">Published</SelectItem>
							<SelectItem value="archived">Archived</SelectItem>
						</SelectContent>
					</Select>
				)}
			</div>

			{/* Main form */}
			<Form {...form}>
				<form onSubmit={form.handleSubmit(onSubmit)}>
					<Tabs
						defaultValue="basic"
						value={activeTab}
						onValueChange={setActiveTab}
						className="w-full"
					>
						<TabsList className="grid grid-cols-3">
							<TabsTrigger value="basic">Basic Information</TabsTrigger>
							<TabsTrigger value="content">Content</TabsTrigger>
							{showPreview && (
								<TabsTrigger value="preview">Preview</TabsTrigger>
							)}
						</TabsList>

						{/* Basic Information Tab */}
						<TabsContent value="basic" className="space-y-4 py-4">
							<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
								{/* Left column - Metadata */}
								<div className="md:col-span-2 space-y-4">
									<Card>
										<CardHeader>
											<CardTitle>Work Details</CardTitle>
											<CardDescription>
												Basic information about this literary work
											</CardDescription>
										</CardHeader>
										<CardContent className="space-y-4">
											{/* Title */}
											<FormField
												control={form.control as any}
												name="title"
												render={({ field }) => (
													<FormItem>
														<FormLabel>Title</FormLabel>
														<FormControl>
															<Input
																placeholder="Enter the title of your work"
																{...field}
																disabled={isLoading || readOnly}
															/>
														</FormControl>
														<FormMessage />
													</FormItem>
												)}
											/>

											{/* Subtitle */}
											<FormField
												control={form.control as any}
												name="subtitle"
												render={({ field }) => (
													<FormItem>
														<FormLabel>Subtitle (optional)</FormLabel>
														<FormControl>
															<Input
																placeholder="Enter a subtitle if applicable"
																{...field}
																disabled={isLoading || readOnly}
															/>
														</FormControl>
														<FormMessage />
													</FormItem>
												)}
											/>

											{/* Author */}
											<FormField
												control={form.control as any}
												name="authorId"
												render={({ field }) => (
													<FormItem>
														<FormLabel>Author</FormLabel>
														<Select
															onValueChange={field.onChange}
															defaultValue={field.value}
															disabled={isLoading || readOnly}
														>
															<FormControl>
																<SelectTrigger>
																	<SelectValue placeholder="Select an author" />
																</SelectTrigger>
															</FormControl>
															<SelectContent>
																{authors.map((author) => (
																	<SelectItem
																		key={author.id.toString()}
																		value={author.id.toString()}
																	>
																		{author.name}
																	</SelectItem>
																))}
															</SelectContent>
														</Select>
														<FormMessage />
													</FormItem>
												)}
											/>

											<div className="grid grid-cols-2 gap-4">
												{/* Language */}
												<FormField
													control={form.control as any}
													name="language"
													render={({ field }) => (
														<FormItem>
															<FormLabel>Language</FormLabel>
															<Select
																onValueChange={field.onChange}
																defaultValue={field.value}
																disabled={isLoading || readOnly}
															>
																<FormControl>
																	<SelectTrigger>
																		<SelectValue placeholder="Select language" />
																	</SelectTrigger>
																</FormControl>
																<SelectContent>
																	{languages.map((language) => (
																		<SelectItem
																			key={language.code}
																			value={language.code}
																		>
																			{language.name}
																		</SelectItem>
																	))}
																</SelectContent>
															</Select>
															<FormMessage />
														</FormItem>
													)}
												/>

												{/* Publication Year */}
												<FormField
													control={form.control as any}
													name="publicationYear"
													render={({ field }) => (
														<FormItem>
															<FormLabel>Publication Year</FormLabel>
															<FormControl>
																<Input
																	placeholder="e.g. 1866"
																	{...field}
																	disabled={isLoading || readOnly}
																/>
															</FormControl>
															<FormMessage />
														</FormItem>
													)}
												/>
											</div>

											{/* Description */}
											<FormField
												control={form.control as any}
												name="description"
												render={({ field }) => (
													<FormItem>
														<FormLabel>Description</FormLabel>
														<FormControl>
															<Textarea
																placeholder="Enter a brief description or synopsis"
																className="min-h-[120px]"
																{...field}
																disabled={isLoading || readOnly}
															/>
														</FormControl>
														<FormMessage />
													</FormItem>
												)}
											/>

											{/* Genres */}
											<FormItem>
												<FormLabel>Genres</FormLabel>
												<TagInput
													placeholder="Add genres"
													tags={selectedGenres}
													onTagsChange={setSelectedGenres}
													suggestions={genres.map((genre) => ({
														value: genre.name,
														label: genre.name,
													}))}
													allowNew={true}
													readOnly={readOnly}
													disabled={isLoading}
												/>
												<FormDescription>
													Select from existing genres or create new ones
												</FormDescription>
											</FormItem>
										</CardContent>
									</Card>

									{/* Translation Fields (if applicable) */}
									{showTranslationFields && (
										<Card>
											<CardHeader>
												<CardTitle>Translation Information</CardTitle>
												<CardDescription>
													Details about this translation
												</CardDescription>
											</CardHeader>
											<CardContent className="space-y-4">
												<div className="grid grid-cols-2 gap-4">
													<div>
														<Label htmlFor="translator">Translator</Label>
														<Input
															id="translator"
															placeholder="Translator's name"
															disabled={isLoading || readOnly}
														/>
													</div>
													<div>
														<Label htmlFor="translation-year">
															Translation Year
														</Label>
														<Input
															id="translation-year"
															placeholder="e.g. 2020"
															disabled={isLoading || readOnly}
														/>
													</div>
												</div>
												<div>
													<Label htmlFor="translation-notes">
														Translation Notes
													</Label>
													<Textarea
														id="translation-notes"
														placeholder="Enter any notes about this translation"
														className="min-h-[100px]"
														disabled={isLoading || readOnly}
													/>
												</div>
											</CardContent>
										</Card>
									)}
								</div>

								{/* Right column - Cover Image */}
								<div>
									<Card>
										<CardHeader>
											<CardTitle>Cover Image</CardTitle>
											<CardDescription>
												Upload a cover image for your work
											</CardDescription>
										</CardHeader>
										<CardContent className="space-y-4">
											{/* Image preview */}
											{coverPreview ? (
												<div className="relative aspect-[2/3] rounded-md overflow-hidden border">
													<img
														src={coverPreview}
														alt="Cover preview"
														className="object-cover w-full h-full"
													/>
													{!readOnly && (
														<Button
															variant="destructive"
															size="icon"
															className="absolute top-2 right-2 h-8 w-8 rounded-full"
															onClick={() => {
																setCoverImage(null);
																setCoverPreview(undefined);
															}}
															type="button"
															disabled={isLoading}
														>
															<Trash2 className="h-4 w-4" />
															<span className="sr-only">
																Remove cover image
															</span>
														</Button>
													)}
												</div>
											) : (
												<div className="aspect-[2/3] rounded-md border border-dashed flex items-center justify-center bg-muted/50">
													<div className="text-center p-4">
														<BookText className="h-8 w-8 mx-auto text-muted-foreground" />
														<p className="text-sm text-muted-foreground mt-2">
															No cover image
														</p>
													</div>
												</div>
											)}

											{/* File uploader */}
											{!readOnly && (
												<FileUploader
													onFilesSelected={handleCoverImageSelect}
													accept=".jpg, .jpeg, .png"
													maxFiles={1}
													maxSize={5 * 1024 * 1024} // 5MB
													buttonText="Select cover image"
													showSelectedFiles={false}
													disabled={isLoading}
												/>
											)}
										</CardContent>
									</Card>
								</div>
							</div>
						</TabsContent>

						{/* Content Tab */}
						<TabsContent value="content" className="py-4">
							<Card>
								<CardHeader>
									<CardTitle>Work Content</CardTitle>
									<CardDescription>
										Enter the content of your literary work
									</CardDescription>
									{!form.getValues("content") && (
										<Alert className="bg-amber-50 text-amber-800 border-amber-200 dark:bg-amber-900/20 dark:text-amber-400 dark:border-amber-700/30">
											<AlertCircle className="h-4 w-4" />
											<AlertTitle>No content yet</AlertTitle>
											<AlertDescription>
												Enter the complete text of your work in this section.
											</AlertDescription>
										</Alert>
									)}
								</CardHeader>
								<CardContent>
									<div className="min-h-[500px]">
										<RichTextEditor
											value={workContent}
											onChange={setWorkContent}
											placeholder="Enter your work content here..."
											disabled={readOnly || isLoading}
										/>
									</div>
								</CardContent>
							</Card>
						</TabsContent>

						{/* Preview Tab */}
						{showPreview && (
							<TabsContent value="preview" className="py-4">
								<Card>
									<CardHeader>
										<CardTitle>Preview</CardTitle>
										<CardDescription>
											Preview how your work will appear to readers
										</CardDescription>
										<div className="flex items-center gap-2">
											<Button
												type="button"
												variant={previewMode ? "default" : "outline"}
												size="sm"
												onClick={() => setPreviewMode(false)}
											>
												<BookOpen className="h-4 w-4 mr-2" />
												Work View
											</Button>
											{/* Additional preview modes could be added here */}
										</div>
									</CardHeader>
									<CardContent>
										<div className="border rounded-lg p-6 min-h-[500px]">
											{/* Preview title */}
											<h1 className="text-3xl font-bold font-serif mb-2">
												{watchedValues.title || "Untitled Work"}
											</h1>

											{/* Preview subtitle */}
											{watchedValues.subtitle && (
												<h2 className="text-xl text-muted-foreground font-serif mb-4">
													{watchedValues.subtitle}
												</h2>
											)}

											{/* Author and metadata */}
											<div className="flex items-center gap-2 mb-6">
												<span className="text-sm text-muted-foreground">
													by{" "}
													{authors.find(
														(a) => a.id.toString() === watchedValues.authorId,
													)?.name || "Unknown Author"}
												</span>
												{watchedValues.publicationYear && (
													<span className="text-sm text-muted-foreground">
														• {watchedValues.publicationYear}
													</span>
												)}
											</div>

											<Separator className="my-4" />

											{/* Content preview */}
											<div className="prose dark:prose-invert max-w-none">
												{workContent ? (
													<div
														dangerouslySetInnerHTML={{ __html: workContent }}
													/>
												) : (
													<p className="text-muted-foreground italic">
														No content to preview. Add content in the "Content"
														tab.
													</p>
												)}
											</div>
										</div>
									</CardContent>
								</Card>
							</TabsContent>
						)}
					</Tabs>

					{/* Form actions */}
					<div className="flex justify-between mt-6">
						<div>
							{work?.id && onDelete && !readOnly && (
								<Button
									type="button"
									variant="destructive"
									onClick={() => onDelete(work.id!)}
									disabled={isLoading}
								>
									Delete Work
								</Button>
							)}
						</div>
						<div className="flex gap-2">
							<Button
								type="button"
								variant="outline"
								onClick={onCancel}
								disabled={isLoading}
							>
								Cancel
							</Button>
							{!readOnly && (
								<Button
									type="submit"
									disabled={isLoading || !form.formState.isValid}
								>
									{isLoading
										? "Saving..."
										: work?.id
											? "Update Work"
											: "Create Work"}
								</Button>
							)}
						</div>
					</div>
				</form>
			</Form>
		</div>
	);
}

export default WorkEditor;
