import { createFileRoute, Link } from "@tanstack/react-router";
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import {
	useApiKeys,
	useAuth,
	useCreateApiKey,
	useDeleteApiKey,
} from "../hooks/useAuth";
import { useCurrency } from "../hooks/useCurrency";
import { useExportItems, useImportItems } from "../hooks/useItems";
import { useLanguage } from "../hooks/useLanguage";
import { useUpdateSetting } from "../hooks/useSettings";
import { useWeightUnit } from "../hooks/useWeightUnit";
import type { Currency, WeightUnit } from "../lib/formatters";
import i18n from "../lib/i18n";

const LANGUAGES = [
	{ value: "en", label: "English" },
	{ value: "de", label: "Deutsch" },
];

const UNITS: WeightUnit[] = ["g", "oz", "lb", "kg"];
const CURRENCIES: { value: Currency; label: string }[] = [
	{ value: "USD", label: "$" },
	{ value: "EUR", label: "\u20AC" },
	{ value: "GBP", label: "\u00A3" },
	{ value: "JPY", label: "\u00A5" },
	{ value: "CAD", label: "CA$" },
	{ value: "AUD", label: "A$" },
];

export const Route = createFileRoute("/settings")({
	component: SettingsPage,
});

function ApiKeySection() {
	const { t } = useTranslation("settings");
	const { data: keys } = useApiKeys();
	const createKey = useCreateApiKey();
	const deleteKey = useDeleteApiKey();
	const [name, setName] = useState("");
	const [newKey, setNewKey] = useState<string | null>(null);

	async function handleCreate(e: React.FormEvent) {
		e.preventDefault();
		const result = await createKey.mutateAsync({ name });
		setNewKey(result.key);
		setName("");
	}

	return (
		<div className="space-y-3">
			<h3 className="text-sm font-medium text-gray-900">
				{t("apiKeys.title")}
			</h3>
			<p className="text-xs text-gray-500">{t("apiKeys.description")}</p>

			{newKey && (
				<div className="bg-amber-50 border border-amber-200 rounded-lg p-3">
					<p className="text-xs font-medium text-amber-800 mb-1">
						{t("apiKeys.copyWarning")}
					</p>
					<code className="text-xs text-amber-900 break-all select-all">
						{newKey}
					</code>
					<button
						type="button"
						onClick={() => setNewKey(null)}
						className="mt-2 block text-xs text-amber-700 hover:text-amber-900"
					>
						{t("common:actions.dismiss")}
					</button>
				</div>
			)}

			<form onSubmit={handleCreate} className="flex gap-2">
				<input
					type="text"
					placeholder={t("apiKeys.namePlaceholder")}
					value={name}
					onChange={(e) => setName(e.target.value)}
					required
					className="flex-1 px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-200"
				/>
				<button
					type="submit"
					disabled={createKey.isPending}
					className="px-4 py-2 text-sm font-medium text-white bg-gray-700 hover:bg-gray-800 disabled:opacity-50 rounded-lg transition-colors"
				>
					{t("common:actions.create")}
				</button>
			</form>

			{keys && keys.length > 0 && (
				<div className="space-y-2">
					{keys.map((key) => (
						<div
							key={key.id}
							className="flex items-center justify-between py-2 px-3 bg-gray-50 rounded-lg"
						>
							<div>
								<span className="text-sm text-gray-900">{key.name}</span>
								<span className="text-xs text-gray-400 ml-2">
									{key.keyPrefix}...
								</span>
							</div>
							<button
								type="button"
								onClick={() => deleteKey.mutate(key.id)}
								className="text-xs text-red-500 hover:text-red-700"
							>
								{t("common:actions.revoke")}
							</button>
						</div>
					))}
				</div>
			)}
		</div>
	);
}

function ImportExportSection() {
	const { t } = useTranslation("settings");
	const exportItems = useExportItems();
	const importItems = useImportItems();
	const fileInputRef = useRef<HTMLInputElement>(null);
	const [importResult, setImportResult] = useState<{
		imported: number;
		createdCategories: string[];
		errors: string[];
	} | null>(null);

	async function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
		const file = e.target.files?.[0];
		if (!file) return;
		setImportResult(null);
		try {
			const result = await importItems.mutateAsync(file);
			setImportResult(result);
		} catch (err) {
			setImportResult({
				imported: 0,
				createdCategories: [],
				errors: [(err as Error).message],
			});
		}
		// Reset so the same file can be imported again if needed
		if (fileInputRef.current) fileInputRef.current.value = "";
	}

	return (
		<div className="space-y-3">
			<h3 className="text-sm font-medium text-gray-900">
				{t("importExport.title")}
			</h3>
			<p className="text-xs text-gray-500">{t("importExport.description")}</p>

			<div className="flex flex-wrap gap-2">
				<button
					type="button"
					onClick={exportItems}
					className="px-4 py-2 text-sm font-medium text-white bg-gray-700 hover:bg-gray-800 rounded-lg transition-colors"
				>
					{t("importExport.export")}
				</button>

				<label className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-200 hover:bg-gray-50 rounded-lg transition-colors cursor-pointer">
					{importItems.isPending
						? t("importExport.importing")
						: t("importExport.import")}
					<input
						ref={fileInputRef}
						type="file"
						accept=".csv"
						className="hidden"
						disabled={importItems.isPending}
						onChange={handleFileChange}
					/>
				</label>
			</div>

			{importResult && (
				<div
					className={`rounded-lg p-3 text-xs space-y-1 ${
						importResult.errors.length > 0 && importResult.imported === 0
							? "bg-red-50 border border-red-200 text-red-700"
							: "bg-green-50 border border-green-200 text-green-700"
					}`}
				>
					{importResult.imported > 0 && (
						<p className="font-medium">
							{t("importExport.imported", { count: importResult.imported })}
						</p>
					)}
					{importResult.createdCategories.length > 0 && (
						<p>
							{t("importExport.newCategories", {
								categories: importResult.createdCategories.join(", "),
							})}
						</p>
					)}
					{importResult.errors.map((err, i) => (
						// biome-ignore lint/suspicious/noArrayIndexKey: static error list
						<p key={i} className="text-red-600">
							{err}
						</p>
					))}
					{importResult.imported === 0 && importResult.errors.length === 0 && (
						<p>{t("importExport.noItemsFound")}</p>
					)}
				</div>
			)}
		</div>
	);
}

const LOCALE_CURRENCY_MAP: Record<string, Currency> = {
	de: "EUR",
	fr: "EUR",
	es: "EUR",
	it: "EUR",
	nl: "EUR",
	pt: "EUR",
	en: "USD",
	ja: "JPY",
};

function getSuggestedCurrency(): Currency | null {
	try {
		const lang = navigator.language;
		// Check full locale first (e.g., en-GB → GBP)
		if (lang.startsWith("en-GB")) return "GBP";
		if (lang.startsWith("en-AU")) return "AUD";
		if (lang.startsWith("en-CA") || lang.startsWith("fr-CA")) return "CAD";
		// Fall back to language prefix
		const prefix = lang.split("-")[0];
		return LOCALE_CURRENCY_MAP[prefix] ?? null;
	} catch {
		return null;
	}
}

function SettingsPage() {
	const { t } = useTranslation("settings");
	const unit = useWeightUnit();
	const language = useLanguage();
	const { currency, showConversions } = useCurrency();
	const updateSetting = useUpdateSetting();
	const { data: auth } = useAuth();
	const [suggestionDismissed, setSuggestionDismissed] = useState(false);

	const suggestedCurrency = getSuggestedCurrency();
	const showSuggestion =
		!suggestionDismissed && suggestedCurrency && suggestedCurrency !== currency;

	return (
		<div className="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
			<div className="mb-6">
				<Link
					to="/"
					className="text-sm text-gray-500 hover:text-gray-700 mb-2 inline-block"
				>
					&larr; {t("common:actions.back")}
				</Link>
				<h1 className="text-xl font-semibold text-gray-900">{t("title")}</h1>
			</div>

			{showSuggestion && (
				<div className="bg-blue-50 border border-blue-100 rounded-xl px-4 py-3 mb-4 flex items-center justify-between">
					<span className="text-sm text-blue-700">
						Based on your location, we suggest{" "}
						{CURRENCIES.find((c) => c.value === suggestedCurrency)?.label ??
							suggestedCurrency}{" "}
						({suggestedCurrency})
					</span>
					<button
						type="button"
						onClick={() => {
							updateSetting.mutate({
								key: "currency",
								value: suggestedCurrency,
							});
							setSuggestionDismissed(true);
						}}
						className="text-sm font-medium text-blue-700 hover:text-blue-800 underline ml-3"
					>
						Use{" "}
						{CURRENCIES.find((c) => c.value === suggestedCurrency)?.label ??
							suggestedCurrency}
					</button>
				</div>
			)}

			<div className="bg-white rounded-xl border border-gray-100 p-5 space-y-6">
				<div className="flex items-center justify-between">
					<div>
						<h3 className="text-sm font-medium text-gray-900">
							{t("language.title")}
						</h3>
						<p className="text-xs text-gray-500 mt-0.5">
							{t("language.description")}
						</p>
					</div>
					<div className="flex items-center gap-1 bg-gray-100 rounded-full px-1 py-0.5">
						{LANGUAGES.map((lang) => (
							<button
								key={lang.value}
								type="button"
								onClick={() => {
									updateSetting.mutate({ key: "language", value: lang.value });
									i18n.changeLanguage(lang.value);
								}}
								className={`px-2.5 py-1 text-xs rounded-full transition-colors ${
									language === lang.value
										? "bg-white text-gray-700 shadow-sm font-medium"
										: "text-gray-400 hover:text-gray-600"
								}`}
							>
								{lang.label}
							</button>
						))}
					</div>
				</div>

				<div className="border-t border-gray-100" />

				<div className="flex items-center justify-between">
					<div>
						<h3 className="text-sm font-medium text-gray-900">
							{t("weightUnit.title")}
						</h3>
						<p className="text-xs text-gray-500 mt-0.5">
							{t("weightUnit.description")}
						</p>
					</div>
					<div className="flex items-center gap-1 bg-gray-100 rounded-full px-1 py-0.5">
						{UNITS.map((u) => (
							<button
								key={u}
								type="button"
								onClick={() =>
									updateSetting.mutate({
										key: "weightUnit",
										value: u,
									})
								}
								className={`px-2.5 py-1 text-xs rounded-full transition-colors ${
									unit === u
										? "bg-white text-gray-700 shadow-sm font-medium"
										: "text-gray-400 hover:text-gray-600"
								}`}
							>
								{u}
							</button>
						))}
					</div>
				</div>

				<div className="border-t border-gray-100" />

				<div className="flex items-center justify-between">
					<div>
						<h3 className="text-sm font-medium text-gray-900">
							{t("currency.title")}
						</h3>
						<p className="text-xs text-gray-500 mt-0.5">
							{t("currency.description")}
						</p>
					</div>
					<div className="flex items-center gap-1 bg-gray-100 rounded-full px-1 py-0.5">
						{CURRENCIES.map((c) => (
							<button
								key={c.value}
								type="button"
								onClick={() =>
									updateSetting.mutate({
										key: "currency",
										value: c.value,
									})
								}
								className={`px-2.5 py-1 text-xs rounded-full transition-colors ${
									currency === c.value
										? "bg-white text-gray-700 shadow-sm font-medium"
										: "text-gray-400 hover:text-gray-600"
								}`}
							>
								{c.label}
							</button>
						))}
					</div>
				</div>

				<div className="border-t border-gray-100" />

				<div className="flex items-center justify-between">
					<div>
						<h3 className="text-sm font-medium text-gray-900">
							Show Converted Prices
						</h3>
						<p className="text-xs text-gray-500 mt-0.5">
							Display approximate conversions when local price is not available
						</p>
					</div>
					<button
						type="button"
						onClick={() =>
							updateSetting.mutate({
								key: "showConversions",
								value: showConversions ? "false" : "true",
							})
						}
						className={`relative w-10 h-5 rounded-full transition-colors ${
							showConversions ? "bg-blue-500" : "bg-gray-200"
						}`}
					>
						<span
							className={`absolute top-0.5 left-0.5 w-4 h-4 rounded-full bg-white shadow-sm transition-transform ${
								showConversions ? "translate-x-5" : "translate-x-0"
							}`}
						/>
					</button>
				</div>
			</div>

			<div className="bg-white rounded-xl border border-gray-100 p-5 space-y-6 mt-4">
				<ImportExportSection />
			</div>

			{auth?.authenticated && (
				<div className="bg-white rounded-xl border border-gray-100 p-5 space-y-6 mt-4">
					<ApiKeySection />
				</div>
			)}
		</div>
	);
}
