"use client";

import React from "react";
import Link from "next/link";
import { CalendarCheck, RefreshCw } from "lucide-react";

import { getDays, getMonths, getYears } from "@/lib/frontend/apiClient";
import { dayPath, monthPath, yearPath } from "@/lib/frontend/routes";
import { sortNumericStringsDesc } 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 { LOADING_UI_DELAY_MS } from "@/lib/frontend/ui/uxTimings";

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";

export default function DaysExplorer({ branch, year, month }) {
	const daysLoadFn = React.useCallback(
		() => getDays(branch, year, month),
		[branch, year, month],
	);
	const daysQuery = useExplorerQuery(daysLoadFn, [daysLoadFn]);

	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 mapped = React.useMemo(
		() => mapExplorerError(daysQuery.error),
		[daysQuery.error],
	);

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

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

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

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

	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 breadcrumbsNode = (
		<ExplorerBreadcrumbs
			branch={branch}
			year={year}
			month={month}
			yearOptions={yearOptions}
			monthOptions={monthOptions}
		/>
	);

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

	if (showLoadingUi) {
		return (
			<ExplorerPageShell
				title="Tage"
				description="Wählen Sie einen Tag aus."
				breadcrumbs={breadcrumbsNode}
				actions={actions}
			>
				<ExplorerSectionCard title="Verfügbare Tage" description="Lade Daten…">
					<ExplorerLoading variant="grid" count={16} />
				</ExplorerSectionCard>
			</ExplorerPageShell>
		);
	}

	if (daysQuery.status === "loading") {
		return (
			<ExplorerPageShell
				title="Tage"
				description="Wählen Sie einen Tag aus."
				breadcrumbs={breadcrumbsNode}
				actions={actions}
			>
				<div className="h-16" aria-hidden="true" />
			</ExplorerPageShell>
		);
	}

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

		if (mapped.kind === "notfound") {
			return (
				<ExplorerPageShell
					title="Tage"
					description="Wählen Sie einen Tag aus."
					breadcrumbs={breadcrumbsNode}
					actions={actions}
				>
					<ExplorerNotFound
						upHref={yearPath(branch, year)}
						branchRootHref={yearPath(branch, year)}
					/>
				</ExplorerPageShell>
			);
		}

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

		return (
			<ExplorerPageShell
				title="Tage"
				description="Wählen Sie einen Tag aus."
				breadcrumbs={breadcrumbsNode}
				actions={actions}
			>
				<ExplorerSectionCard title="Verfügbare Tage" description="Fehler">
					<ExplorerError
						title={mapped.title}
						description={mapped.description}
						onRetry={daysQuery.retry}
					/>
				</ExplorerSectionCard>
			</ExplorerPageShell>
		);
	}

	const days = Array.isArray(daysQuery.data?.days) ? daysQuery.data.days : [];
	const sorted = sortNumericStringsDesc(days);

	return (
		<ExplorerPageShell
			title="Tage"
			description="Wählen Sie einen Tag aus."
			breadcrumbs={breadcrumbsNode}
			actions={actions}
		>
			<ExplorerSectionCard
				title="Verfügbare Tage"
				description={`Niederlassung ${branch} • ${year}/${month}`}
				headerRight={
					<span className="rounded-md bg-muted px-2 py-1 text-xs text-muted-foreground">
						{sorted.length} Tag{sorted.length === 1 ? "" : "e"}
					</span>
				}
			>
				{sorted.length === 0 ? (
					<ExplorerEmpty
						title="Keine Tage gefunden"
						description="Für diesen Monat wurden keine Tage gefunden."
						upHref={monthPath(branch, year, month)}
					/>
				) : (
					<div className="grid grid-cols-2 gap-2 sm:grid-cols-4 md:grid-cols-6">
						{sorted.map((d) => (
							<Button
								key={d}
								variant="outline"
								className="w-full justify-start"
								asChild
							>
								<Link href={dayPath(branch, year, month, d)}>
									<CalendarCheck className="h-4 w-4" />
									{d}
								</Link>
							</Button>
						))}
					</div>
				)}
			</ExplorerSectionCard>
		</ExplorerPageShell>
	);
}
