import { useQuery } from "@tanstack/react-query";
import { ChevronLeft, ChevronRight, Grid, List } from "lucide-react";
import { useEffect, useState } from "react";
import { useLocation } from "wouter";
import { SearchBar } from "@/components/common/SearchBar";
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 type { WorkWithAuthor } from "@/lib/types";

interface FilterState {
	language?: string;
	type?: string;
	yearStart?: number;
	yearEnd?: number;
	tags?: number[];
	query?: string;
	sort?: string;
	page: number;
}

export default function Explore() {
	const [location] = useLocation();
	const [filters, setFilters] = useState<FilterState>({
		page: 1,
	});
	const [viewMode, setViewMode] = useState<"list" | "grid">("list");

	// Parse URL search params on initial load
	useEffect(() => {
		const searchParams = new URLSearchParams(location.split("?")[1]);

		const newFilters: FilterState = { page: 1 };

		if (searchParams.has("q")) {
			newFilters.query = searchParams.get("q") || undefined;
		}

		if (searchParams.has("language")) {
			newFilters.language = searchParams.get("language") || undefined;
		}

		if (searchParams.has("type")) {
			newFilters.type = searchParams.get("type") || undefined;
		}

		if (searchParams.has("yearStart")) {
			newFilters.yearStart =
				parseInt(searchParams.get("yearStart") || "0", 10) || undefined;
		}

		if (searchParams.has("yearEnd")) {
			newFilters.yearEnd =
				parseInt(searchParams.get("yearEnd") || "0", 10) || undefined;
		}

		if (searchParams.has("tags")) {
			newFilters.tags =
				searchParams.get("tags")?.split(",").map(Number) || undefined;
		}

		if (searchParams.has("sort")) {
			newFilters.sort = searchParams.get("sort") || undefined;
		}

		if (searchParams.has("page")) {
			newFilters.page = parseInt(searchParams.get("page") || "1", 10);
		}

		setFilters(newFilters);
	}, [location]);

	// Build API query string based on filters
	const getQueryString = () => {
		const params = new URLSearchParams();

		if (filters.query) {
			params.append("q", filters.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(","));
		}

		if (filters.sort) {
			params.append("sort", filters.sort);
		}

		// Pagination (we'll use limit/offset)
		const limit = 10;
		const offset = (filters.page - 1) * limit;
		params.append("limit", limit.toString());
		params.append("offset", offset.toString());

		return params.toString();
	};

	const queryString = getQueryString();

	const { data: works, isLoading } = useQuery<WorkWithAuthor[]>({
		queryKey: [`/api/filter?${queryString}`],
		select: (data) =>
			data.map((work) => ({
				...work,
				tags: work.tags?.map((tag) =>
					typeof tag === "string" ? { name: tag } : tag,
				),
			})),
	});

	const { data: tags } = useQuery({
		queryKey: ["/api/tags"],
	});

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

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

	// Generate page numbers for pagination
	const totalWorks = works?.length || 0;
	const workPerPage = 10;
	const totalPages = Math.ceil(totalWorks / workPerPage);
	const pageNumbers = [];

	const maxPageButtons = 5;
	let startPage = Math.max(1, filters.page - Math.floor(maxPageButtons / 2));
	const endPage = Math.min(totalPages, startPage + maxPageButtons - 1);

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

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

	return (
		<PageLayout>
			<div className="max-w-[var(--content-width)] mx-auto px-4 md:px-6 py-8">
				<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
					<div>
						<h1 className="text-2xl md:text-3xl font-bold font-serif text-navy dark:text-cream">
							Explore Literature
						</h1>
						<p className="text-navy/70 dark:text-cream/70 mt-1">
							Discover works across languages, genres, and time periods
						</p>
					</div>
					<div className="flex items-center gap-3">
						<SearchBar />
					</div>
				</div>

				<div className="flex flex-col lg:flex-row gap-8">
					{/* Filters sidebar */}
					<FilterSidebar
						filters={filters}
						onFilterChange={handleFilterChange}
						tags={tags || []}
					/>

					{/* Results */}
					<div className="flex-1">
						<div className="mb-4 flex items-center justify-between">
							<div className="text-sm text-navy/70 dark:text-cream/70">
								Showing{" "}
								<span className="font-medium text-navy dark:text-cream">
									{works?.length || 0}
								</span>{" "}
								results
								{filters.query && (
									<span>
										{" "}
										for{" "}
										<span className="font-medium text-navy dark:text-cream">
											"{filters.query}"
										</span>
									</span>
								)}
							</div>
							<div className="flex items-center gap-2">
								<span className="text-sm text-navy/70 dark:text-cream/70">
									Display:
								</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>

						{isLoading ? (
							<div className="space-y-4">
								{Array.from({ length: 5 }).map((_, i) => (
									<div
										key={i}
										className="h-40 bg-cream dark:bg-dark-surface rounded-lg animate-pulse"
									></div>
								))}
							</div>
						) : viewMode === "list" ? (
							<div className="space-y-3">
								{works?.map((work) => (
									<WorkCard key={work.id} work={work} />
								))}
							</div>
						) : (
							<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
								{works?.map((work) => (
									<WorkCard key={work.id} work={work} grid />
								))}
							</div>
						)}

						{/* Pagination */}
						{totalPages > 1 && (
							<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, filters.page - 1))
										}
										disabled={filters.page === 1}
									>
										<ChevronLeft className="h-4 w-4" />
										<span className="sr-only">Previous</span>
									</Button>

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

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

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

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