"use client";

import React from "react";
import { Eye, FileText, RefreshCw } from "lucide-react";

import {
	getFiles,
	getDays,
	getMonths,
	getYears,
} from "@/lib/frontend/apiClient";
import { dayPath, monthPath, branchPath } from "@/lib/frontend/routes";
import { sortFilesByNameAsc } from "@/lib/frontend/explorer/sorters";
import { mapExplorerError } from "@/lib/frontend/explorer/errorMapping";
import { buildLoginUrl, LOGIN_REASONS } from "@/lib/frontend/authRedirect";
import { useExplorerQuery } from "@/lib/frontend/hooks/useExplorerQuery";
import { useDebouncedVisibility } from "@/lib/frontend/hooks/useDebouncedVisibility";
import { buildPdfUrl } from "@/lib/frontend/explorer/pdfUrl";

import ExplorerBreadcrumbs from "@/components/explorer/breadcrumbs/ExplorerBreadcrumbs";
import ExplorerPageShell from "@/components/explorer/ExplorerPageShell";
import ExplorerSectionCard from "@/components/explorer/ExplorerSectionCard";
import ExplorerLoading from "@/components/explorer/states/ExplorerLoading";
import ExplorerEmpty from "@/components/explorer/states/ExplorerEmpty";
import ExplorerError from "@/components/explorer/states/ExplorerError";
import ExplorerNotFound from "@/components/explorer/states/ExplorerNotFound";

import ForbiddenView from "@/components/system/ForbiddenView";
import { Button } from "@/components/ui/button";
import {
	Table,
	TableHeader,
	TableBody,
	TableRow,
	TableHead,
	TableCell,
	TableCaption,
} from "@/components/ui/table";

const LOADING_DELAY_MS = 300;

export default function FilesExplorer({ branch, year, month, day }) {
	const filesLoadFn = React.useCallback(
		() => getFiles(branch, year, month, day),
		[branch, year, month, day],
	);
	const filesQuery = useExplorerQuery(filesLoadFn, [filesLoadFn]);

	const yearsLoadFn = React.useCallback(() => getYears(branch), [branch]);
	const yearsQuery = useExplorerQuery(yearsLoadFn, [yearsLoadFn]);

	const monthsLoadFn = React.useCallback(
		() => getMonths(branch, year),
		[branch, year],
	);
	const monthsQuery = useExplorerQuery(monthsLoadFn, [monthsLoadFn]);

	const daysLoadFn = React.useCallback(
		() => getDays(branch, year, month),
		[branch, year, month],
	);
	const daysQuery = useExplorerQuery(daysLoadFn, [daysLoadFn]);

	const mapped = React.useMemo(
		() => mapExplorerError(filesQuery.error),
		[filesQuery.error],
	);

	const showLoadingUi = useDebouncedVisibility(
		filesQuery.status === "loading",
		{
			delayMs: LOADING_DELAY_MS,
			minVisibleMs: 0,
		},
	);

	React.useEffect(() => {
		if (mapped?.kind !== "unauthenticated") return;

		const next =
			typeof window !== "undefined"
				? `${window.location.pathname}${window.location.search}`
				: dayPath(branch, year, month, day);

		window.location.replace(
			buildLoginUrl({ reason: LOGIN_REASONS.EXPIRED, next }),
		);
	}, [mapped?.kind, branch, year, month, day]);

	const yearOptions =
		yearsQuery.status === "success" && Array.isArray(yearsQuery.data?.years)
			? yearsQuery.data.years
			: null;

	const monthOptions =
		monthsQuery.status === "success" && Array.isArray(monthsQuery.data?.months)
			? monthsQuery.data.months
			: null;

	const dayOptions =
		daysQuery.status === "success" && Array.isArray(daysQuery.data?.days)
			? daysQuery.data.days
			: null;

	const breadcrumbsNode = (
		<ExplorerBreadcrumbs
			branch={branch}
			year={year}
			month={month}
			day={day}
			yearOptions={yearOptions}
			monthOptions={monthOptions}
			dayOptions={dayOptions}
		/>
	);

	const actions = (
		<Button
			variant="outline"
			size="sm"
			onClick={() => {
				filesQuery.retry();
				yearsQuery.retry();
				monthsQuery.retry();
				daysQuery.retry();
			}}
			title="Aktualisieren"
		>
			<RefreshCw className="h-4 w-4" />
			Aktualisieren
		</Button>
	);

	if (showLoadingUi) {
		return (
			<ExplorerPageShell
				title="Dateien"
				description="Lieferscheine für den ausgewählten Tag."
				breadcrumbs={breadcrumbsNode}
				actions={actions}
			>
				<ExplorerSectionCard title="Dateiliste" description="Lade Daten…">
					<ExplorerLoading variant="table" count={8} />
				</ExplorerSectionCard>
			</ExplorerPageShell>
		);
	}

	if (filesQuery.status === "loading") {
		return (
			<ExplorerPageShell
				title="Dateien"
				description="Lieferscheine für den ausgewählten Tag."
				breadcrumbs={breadcrumbsNode}
				actions={actions}
			>
				<div className="h-16" aria-hidden="true" />
			</ExplorerPageShell>
		);
	}

	if (filesQuery.status === "error" && mapped) {
		if (mapped.kind === "forbidden")
			return <ForbiddenView attemptedBranch={branch} />;

		if (mapped.kind === "notfound") {
			return (
				<ExplorerPageShell
					title="Dateien"
					description="Lieferscheine für den ausgewählten Tag."
					breadcrumbs={breadcrumbsNode}
					actions={actions}
				>
					<ExplorerNotFound
						upHref={monthPath(branch, year, month)}
						branchRootHref={branchPath(branch)}
					/>
				</ExplorerPageShell>
			);
		}

		if (mapped.kind === "unauthenticated") {
			return (
				<ExplorerPageShell
					title="Dateien"
					description="Sitzung abgelaufen — Weiterleitung zum Login…"
					breadcrumbs={breadcrumbsNode}
				>
					<div className="h-16" aria-hidden="true" />
				</ExplorerPageShell>
			);
		}

		return (
			<ExplorerPageShell
				title="Dateien"
				description="Lieferscheine für den ausgewählten Tag."
				breadcrumbs={breadcrumbsNode}
				actions={actions}
			>
				<ExplorerSectionCard title="Dateiliste" description="Fehler">
					<ExplorerError
						title={mapped.title}
						description={mapped.description}
						onRetry={filesQuery.retry}
					/>
				</ExplorerSectionCard>
			</ExplorerPageShell>
		);
	}

	const files = Array.isArray(filesQuery.data?.files)
		? filesQuery.data.files
		: [];
	const sorted = sortFilesByNameAsc(files);

	return (
		<ExplorerPageShell
			title="Dateien"
			description="Lieferscheine für den ausgewählten Tag."
			breadcrumbs={breadcrumbsNode}
			actions={actions}
		>
			<ExplorerSectionCard
				title="Dateiliste"
				description={`Niederlassung ${branch} • ${year}/${month}/${day}`}
				headerRight={
					<span className="rounded-md bg-muted px-2 py-1 text-xs text-muted-foreground">
						{sorted.length} Datei{sorted.length === 1 ? "" : "en"}
					</span>
				}
			>
				{sorted.length === 0 ? (
					<ExplorerEmpty
						title="Keine Dateien gefunden"
						description="Für diesen Tag wurden keine Dateien gefunden."
						upHref={monthPath(branch, year, month)}
					/>
				) : (
					<Table>
						<TableCaption>
							Hinweis: PDFs werden in einem neuen Tab geöffnet.
						</TableCaption>

						<TableHeader>
							<TableRow>
								<TableHead>Datei</TableHead>
								<TableHead className="hidden md:table-cell">Pfad</TableHead>
								<TableHead className="text-right">Aktion</TableHead>
							</TableRow>
						</TableHeader>

						<TableBody>
							{sorted.map((f) => {
								const pdfUrl = buildPdfUrl({
									branch,
									year,
									month,
									day,
									filename: f.name,
								});

								return (
									<TableRow key={f.relativePath || f.name}>
										<TableCell className="min-w-0">
											<div className="flex min-w-0 items-start gap-2">
												<FileText className="mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" />
												<div className="min-w-0">
													<p className="truncate font-medium">{f.name}</p>
													<p className="truncate text-xs text-muted-foreground md:hidden">
														{f.relativePath}
													</p>
												</div>
											</div>
										</TableCell>

										<TableCell className="hidden md:table-cell">
											<span className="text-xs text-muted-foreground">
												{f.relativePath}
											</span>
										</TableCell>

										<TableCell className="text-right">
											<Button variant="outline" size="sm" asChild>
												<a
													href={pdfUrl}
													target="_blank"
													rel="noopener noreferrer"
													aria-label={`PDF öffnen: ${f.name}`}
													title={`PDF öffnen: ${f.name}`}
												>
													<Eye className="h-4 w-4" />
													Öffnen
												</a>
											</Button>
										</TableCell>
									</TableRow>
								);
							})}
						</TableBody>
					</Table>
				)}
			</ExplorerSectionCard>
		</ExplorerPageShell>
	);
}
