import type { Tag } from "@shared/schema";
import { useQuery } from "@tanstack/react-query";
import {
	ChevronLeft,
	ChevronRight,
	Filter,
	Grid,
	List,
	Search as SearchIcon,
	X,
} from "lucide-react";
import { useEffect, useState } from "react";
import { useLocation } from "wouter";
import { AuthorChip } from "@/components/common/AuthorChip";
import { WorkCard } from "@/components/common/WorkCard";
import { FilterSidebar } from "@/components/explore/FilterSidebar";
import { PageLayout } from "@/components/layout/PageLayout";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import type { SearchResults, WorkWithAuthor } from "@/lib/types";

export default function Search() {
	const [location, setLocation] = useLocation();
	const [query, setQuery] = useState("");
	const [activeTab, setActiveTab] = useState("all");
	const [viewMode, setViewMode] = useState<"list" | "grid">("list");
	const [showFilters, setShowFilters] = useState(false);
	const [filters, setFilters] = useState<{
		language?: string;
		type?: string;
		yearStart?: number;
		yearEnd?: number;
		tags?: string[];
		page: number;
	}>({
		page: 1,
	});

	// Parse URL parameters
	useEffect(() => {
		const searchParams = new URLSearchParams(location.split("?")[1]);
		const q = searchParams.get("q");
		if (q) {
			setQuery(q);
		}

		// Parse other filter params
		const language = searchParams.get("language");
		const type = searchParams.get("type");
		const yearStart = searchParams.get("yearStart");
		const yearEnd = searchParams.get("yearEnd");
		const tags = searchParams.get("tags");

		setFilters({
			language: language || undefined,
			type: type || undefined,
			yearStart: yearStart ? parseInt(yearStart) : undefined,
			yearEnd: yearEnd ? parseInt(yearEnd) : undefined,
			tags: tags ? tags.split(",") : undefined,
			page: parseInt(searchParams.get("page") || "1"),
		});
	}, [location]);

	// Search results query
	const { data: searchResults, isLoading: searchLoading } = useQuery({
		queryKey: ["/api/search", query],
		queryFn: async (): Promise<SearchResults> => {
			if (!query || query.length < 2) return { works: [], authors: [] };
			// Since /api/search might not exist, we'll assume it returns SearchResults structure
			// If the backend route is missing, this will fail at runtime, but we are fixing types.
			const response = await fetch(
				`/api/search?q=${encodeURIComponent(query)}`,
			);
			return await response.json();
		},
		enabled: query.length >= 2,
		select: (data) => ({
			...data,
			works: data.works.map((work) => ({
				...work,
				tags: work.tags?.map((tag) =>
					typeof tag === "string" ? { name: tag, id: tag, type: "general", createdAt: "" } : tag,
				),
			})),
		}),
	});

	// Filter results query (for advanced filtering)
	const { data: filteredWorks, isLoading: filterLoading } = useQuery({
		queryKey: ["/api/filter", filters],
		queryFn: async (): Promise<WorkWithAuthor[]> => {
			const params = new URLSearchParams();

			if (query) params.append("q", query);
			if (filters.language) params.append("language", filters.language);
			if (filters.type) params.append("type", filters.type);
			if (filters.yearStart)
				params.append("yearStart", filters.yearStart.toString());
			if (filters.yearEnd) params.append("yearEnd", filters.yearEnd.toString());
			if (filters.tags && filters.tags.length > 0)
				params.append("tags", filters.tags.join(","));

			const response = await fetch(`/api/filter?${params.toString()}`);
			return await response.json();
		},
		enabled:
			activeTab === "advanced" &&
			(!!filters.language ||
				!!filters.type ||
				!!filters.yearStart ||
				!!filters.yearEnd ||
				!!(filters.tags && filters.tags.length > 0)),
		select: (data) =>
			data.map((work) => ({
				...work,
				tags: work.tags?.map((tag) =>
					typeof tag === "string" ? { name: tag, id: tag, type: "general", createdAt: "" } : tag,
				),
			})),
	});

	// Get tags for filter sidebar
	const { data: tags } = useQuery<Tag[]>({
		queryKey: ["/api/tags"],
	});

	const handleSearch = (e: React.FormEvent) => {
		e.preventDefault();
		if (query.trim()) {
			const newParams = new URLSearchParams();
			newParams.append("q", query.trim());

			// Only include filter params if we're on advanced tab
			if (activeTab === "advanced") {
				if (filters.language) newParams.append("language", filters.language);
				if (filters.type) newParams.append("type", filters.type);
				if (filters.yearStart)
					newParams.append("yearStart", filters.yearStart.toString());
				if (filters.yearEnd)
					newParams.append("yearEnd", filters.yearEnd.toString());
				if (filters.tags && filters.tags.length > 0)
					newParams.append("tags", filters.tags.join(","));
			}

			setLocation(`/search?${newParams.toString()}`);
		}
	};

	const handleFilterChange = (newFilters: Partial<typeof filters>) => {
		setFilters((prev) => ({ ...prev, ...newFilters, page: 1 }));
	};

	const handleClearSearch = () => {
		setQuery("");
		setLocation("/search");
	};

	const handlePageChange = (newPage: number) => {
		setFilters((prev) => ({ ...prev, page: newPage }));
		window.scrollTo({ top: 0, behavior: "smooth" });
	};

	// Calculate pagination values
	const totalItems =
		activeTab === "works"
			? searchResults?.works.length || 0
			: activeTab === "authors"
				? searchResults?.authors.length || 0
				: activeTab === "advanced"
					? filteredWorks?.length || 0
					: (searchResults?.works.length || 0) +
						(searchResults?.authors.length || 0);

	const itemsPerPage = 10;
	const totalPages = Math.ceil(totalItems / itemsPerPage);
	const currentPage = filters.page;

	// Generate pagination numbers
	const maxPageButtons = 5;
	let startPage = Math.max(1, currentPage - Math.floor(maxPageButtons / 2));
	const endPage = Math.min(totalPages, startPage + maxPageButtons - 1);

	if (endPage - startPage + 1 < maxPageButtons) {
		startPage = Math.max(1, endPage - maxPageButtons + 1);
	}

	const pageNumbers = [];
	for (let i = startPage; i <= endPage; i++) {
		pageNumbers.push(i);
	}

	// Handle display based on current active tab
	// Use any cast here because of the complex type transformation in select causing inference issues with WorkCard props
	const displayWorks =
		activeTab === "advanced" ? filteredWorks || [] : searchResults?.works || [];

	const isLoading =
		(searchLoading && activeTab !== "advanced") ||
		(filterLoading && activeTab === "advanced");

	const hasNoResults =
		query.length >= 2 &&
		!isLoading &&
		(activeTab === "all" ||
			activeTab === "works" ||
			activeTab === "advanced") &&
		displayWorks.length === 0;

	const hasNoAuthors =
		query.length >= 2 &&
		!isLoading &&
		(activeTab === "all" || activeTab === "authors") &&
		(searchResults?.authors.length || 0) === 0;

	return (
		<PageLayout>
			<div className="max-w-[var(--content-width)] mx-auto px-4 md:px-6 py-8">
				<div className="mb-8">
					<h1 className="text-2xl md:text-3xl font-bold font-serif text-primary dark:text-primary-foreground mb-2">
						Search Literary Works
					</h1>
					<p className="text-foreground/70 dark:text-foreground/70">
						Discover literary treasures from our extensive collection
					</p>
				</div>

				{/* Search Form */}
				<form onSubmit={handleSearch} className="mb-8">
					<div className="flex flex-col sm:flex-row gap-2">
						<div className="relative flex-1">
							<SearchIcon className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
							<Input
								type="text"
								placeholder="Search by title, author, or keyword..."
								value={query}
								onChange={(e) => setQuery(e.target.value)}
								className="pl-10 h-11 pr-10"
							/>
							{query && (
								<Button
									type="button"
									variant="ghost"
									size="icon"
									onClick={handleClearSearch}
									className="absolute right-2 top-1/2 transform -translate-y-1/2 h-7 w-7 p-0"
								>
									<X className="h-4 w-4" />
									<span className="sr-only">Clear search</span>
								</Button>
							)}
						</div>
						<Button type="submit" className="h-11 px-6">
							Search
						</Button>
					</div>
				</form>

				{/* Tab Navigation */}
				<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6 gap-4">
					<Tabs
						defaultValue="all"
						value={activeTab}
						onValueChange={setActiveTab}
						className="w-full sm:w-auto"
					>
						<TabsList>
							<TabsTrigger value="all">All Results</TabsTrigger>
							<TabsTrigger value="works">Works</TabsTrigger>
							<TabsTrigger value="authors">Authors</TabsTrigger>
							<TabsTrigger value="advanced">Advanced</TabsTrigger>
						</TabsList>
					</Tabs>

					<div className="flex items-center gap-2">
						<Button
							variant="outline"
							size="sm"
							onClick={() => setShowFilters(!showFilters)}
							className="sm:hidden"
						>
							<Filter className="h-4 w-4 mr-2" />
							{showFilters ? "Hide Filters" : "Show Filters"}
						</Button>
						<div className="hidden sm:flex items-center gap-2">
							<span className="text-sm text-foreground/70">View:</span>
							<Button
								size="icon"
								variant={viewMode === "grid" ? "default" : "ghost"}
								className="h-8 w-8 p-0"
								onClick={() => setViewMode("grid")}
							>
								<Grid className="h-4 w-4" />
								<span className="sr-only">Grid view</span>
							</Button>
							<Button
								size="icon"
								variant={viewMode === "list" ? "default" : "ghost"}
								className="h-8 w-8 p-0"
								onClick={() => setViewMode("list")}
							>
								<List className="h-4 w-4" />
								<span className="sr-only">List view</span>
							</Button>
						</div>
					</div>
				</div>

				<div className="flex flex-col lg:flex-row gap-8">
					{/* Show filter sidebar in Advanced tab */}
					{(activeTab === "advanced" || showFilters) && (
						<FilterSidebar
							filters={filters}
							onFilterChange={handleFilterChange}
							tags={tags || []}
						/>
					)}

					{/* Results area */}
					<div className="flex-1">
						{/* Query info */}
						{query && query.length >= 2 && (
							<div className="mb-4 text-sm text-foreground/70">
								{isLoading ? (
									<p>Searching for "{query}"...</p>
								) : (
									<p>
										Showing results for "
										<span className="font-medium text-foreground">{query}</span>
										"
										{activeTab !== "advanced" && searchResults && (
											<span>
												{" "}
												- {searchResults.works.length} works,{" "}
												{searchResults.authors.length} authors found
											</span>
										)}
										{activeTab === "advanced" && filteredWorks && (
											<span>
												{" "}
												- {filteredWorks.length} works match your filters
											</span>
										)}
									</p>
								)}
							</div>
						)}

						{/* Authors section in all or authors tab */}
						{(activeTab === "all" || activeTab === "authors") &&
							query.length >= 2 && (
								<>
									{activeTab === "all" &&
										searchResults?.authors &&
										searchResults.authors.length > 0 && (
											<h2 className="text-xl font-medium font-serif mb-4 text-primary dark:text-primary-foreground">
												Authors
											</h2>
										)}

									{isLoading ? (
										<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-8">
											{Array.from({ length: 3 }).map((_, i) => (
												<Card key={i} className="bg-card">
													<CardContent className="p-6">
														<div className="flex items-center gap-3 mb-3">
															<div className="w-12 h-12 rounded-full bg-primary/10 animate-pulse"></div>
															<div>
																<div className="h-4 w-32 bg-primary/10 rounded animate-pulse mb-2"></div>
																<div className="h-3 w-24 bg-primary/10 rounded animate-pulse"></div>
															</div>
														</div>
														<div className="h-16 bg-primary/10 rounded animate-pulse"></div>
													</CardContent>
												</Card>
											))}
										</div>
									) : (
										<>
											{searchResults?.authors &&
												searchResults.authors.length > 0 && (
													<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-8">
														{searchResults.authors.map((author) => (
															<Card
																key={author.id}
																className="bg-card hover:shadow-md transition-shadow"
															>
																<CardContent className="p-6">
																	<AuthorChip
																		author={author}
																		size="lg"
																		withLifeDates
																		className="mb-3"
																	/>
																	<p className="text-foreground/80 text-sm line-clamp-3 mb-3">
																		{author.biography?.slice(0, 120)}...
																	</p>
																	<Button
																		size="sm"
																		variant="outline"
																		className="w-full"
																		onClick={() =>
																			setLocation(`/authors/${author.slug}`)
																		}
																	>
																		View Profile
																	</Button>
																</CardContent>
															</Card>
														))}
													</div>
												)}

											{hasNoAuthors && activeTab === "authors" && (
												<div className="text-center py-12 bg-muted/30 rounded-lg mb-8">
													<p className="text-lg text-foreground/70 mb-2">
														No authors found matching "{query}"
													</p>
													<p className="text-sm text-foreground/60">
														Try a different search term or check your spelling
													</p>
												</div>
											)}
										</>
									)}
								</>
							)}

						{/* Works section */}
						{(activeTab === "all" ||
							activeTab === "works" ||
							activeTab === "advanced") && (
							<>
								{activeTab === "all" &&
									searchResults?.works &&
									searchResults.works.length > 0 && (
										<h2 className="text-xl font-medium font-serif mb-4 text-primary dark:text-primary-foreground">
											Works
										</h2>
									)}

								{isLoading ? (
									viewMode === "list" ? (
										<div className="space-y-4">
											{Array.from({ length: 5 }).map((_, i) => (
												<div
													key={i}
													className="h-28 bg-card rounded-lg animate-pulse"
												></div>
											))}
										</div>
									) : (
										<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
											{Array.from({ length: 6 }).map((_, i) => (
												<div
													key={i}
													className="h-48 bg-card rounded-lg animate-pulse"
												></div>
											))}
										</div>
									)
								) : displayWorks.length > 0 ? (
									viewMode === "list" ? (
										<div className="space-y-3">
											{displayWorks.map((work) => (
												// @ts-expect-error - Work type mismatch due to tag transformation
												<WorkCard key={work.id} work={work} />
											))}
										</div>
									) : (
										<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
											{displayWorks.map((work) => (
												// @ts-expect-error - Work type mismatch due to tag transformation
												<WorkCard key={work.id} work={work} grid />
											))}
										</div>
									)
								) : (
									hasNoResults && (
										<div className="text-center py-12 bg-muted/30 rounded-lg">
											<p className="text-lg text-foreground/70 mb-2">
												No works found matching "{query}"
											</p>
											<p className="text-sm text-foreground/60">
												{activeTab === "advanced"
													? "Try adjusting your filters or using different search terms"
													: "Try a different search term or check your spelling"}
											</p>
										</div>
									)
								)}
							</>
						)}

						{/* Entry prompt when search is empty */}
						{query.length < 2 && (
							<div className="text-center py-16 bg-muted/30 rounded-lg">
								<SearchIcon className="h-12 w-12 mx-auto mb-4 text-primary/50" />
								<h3 className="text-xl font-medium mb-2 text-foreground">
									Start Your Literary Journey
								</h3>
								<p className="text-foreground/70 max-w-md mx-auto mb-6">
									Enter a search term above to discover works by title, author,
									or keyword
								</p>
								<div className="flex flex-wrap justify-center gap-2 max-w-md mx-auto">
									{[
										"Poetry",
										"Novel",
										"Tolstoy",
										"Shakespeare",
										"Modernism",
										"Love",
									].map((term) => (
										<Button
											key={term}
											variant="outline"
											size="sm"
											onClick={() => {
												setQuery(term);
												const newParams = new URLSearchParams();
												newParams.append("q", term);
												setLocation(`/search?${newParams.toString()}`);
											}}
										>
											{term}
										</Button>
									))}
								</div>
							</div>
						)}

						{/* Pagination */}
						{totalPages > 1 && !isLoading && (
							<div className="mt-8 flex justify-center">
								<nav
									className="flex items-center gap-1"
									aria-label="Pagination"
								>
									<Button
										variant="ghost"
										size="icon"
										onClick={() =>
											handlePageChange(Math.max(1, currentPage - 1))
										}
										disabled={currentPage === 1}
									>
										<ChevronLeft className="h-4 w-4" />
										<span className="sr-only">Previous</span>
									</Button>

									{startPage > 1 && (
										<>
											<Button
												variant={currentPage === 1 ? "default" : "ghost"}
												size="sm"
												onClick={() => handlePageChange(1)}
											>
												1
											</Button>
											{startPage > 2 && (
												<span className="px-2 text-foreground/60">...</span>
											)}
										</>
									)}

									{pageNumbers.map((number) => (
										<Button
											key={number}
											variant={currentPage === number ? "default" : "ghost"}
											size="sm"
											onClick={() => handlePageChange(number)}
										>
											{number}
										</Button>
									))}

									{endPage < totalPages && (
										<>
											{endPage < totalPages - 1 && (
												<span className="px-2 text-foreground/60">...</span>
											)}
											<Button
												variant={
													currentPage === totalPages ? "default" : "ghost"
												}
												size="sm"
												onClick={() => handlePageChange(totalPages)}
											>
												{totalPages}
											</Button>
										</>
									)}

									<Button
										variant="ghost"
										size="icon"
										onClick={() =>
											handlePageChange(Math.min(totalPages, currentPage + 1))
										}
										disabled={currentPage === totalPages}
									>
										<ChevronRight className="h-4 w-4" />
										<span className="sr-only">Next</span>
									</Button>
								</nav>
							</div>
						)}
					</div>
				</div>
			</div>
		</PageLayout>
	);
}
