import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import { account, auth as authApi } from "../api/client";
import { useAuth } from "../context/AuthContext";
import { Button, Card, Input, PageHeader, Toggle } from "../components/ui";
import { Modal } from "../components/Modal";
import { CodeBlock } from "../components/CodeBlock";

function Section({ title, description, children }: { title: string; description?: string; children: React.ReactNode }) {
	return (
		<Card className="p-4 sm:p-5">
			<h2 className="text-base font-semibold text-text">{title}</h2>
			{description && <p className="mb-4 mt-0.5 text-sm text-muted">{description}</p>}
			<div className={description ? "" : "mt-4"}>{children}</div>
		</Card>
	);
}

export function SettingsPage() {
	const { user, refresh } = useAuth();
	const navigate = useNavigate();

	// Profile
	const [displayName, setDisplayName] = useState(user?.display_name ?? "");
	// Password
	const [curPw, setCurPw] = useState("");
	const [newPw, setNewPw] = useState("");
	// Auto-delete
	const [autoDelete, setAutoDelete] = useState(user?.auto_delete_enabled ?? false);
	const [autoDeleteDays, setAutoDeleteDays] = useState(user?.auto_delete_days ?? 30);
	// 2FA
	const [setup, setSetup] = useState<{ secret: string; otpauth_url: string } | null>(null);
	const [totp, setTotp] = useState("");
	const [disable2faOpen, setDisable2faOpen] = useState(false);
	const [disablePw, setDisablePw] = useState("");
	// Delete account
	const [deleteOpen, setDeleteOpen] = useState(false);
	const [deletePw, setDeletePw] = useState("");

	const saveProfile = async () => {
		try {
			await account.updateProfile(displayName);
			toast.success("Profile updated");
			refresh();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	const savePassword = async () => {
		try {
			await account.changePassword(curPw, newPw);
			toast.success("Password changed");
			setCurPw("");
			setNewPw("");
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	const saveAutoDelete = async (enabled: boolean, days: number) => {
		try {
			const res = await account.updateSettings({ auto_delete_enabled: enabled, auto_delete_days: days });
			setAutoDelete(res.auto_delete_enabled);
			setAutoDeleteDays(res.auto_delete_days);
			toast.success("Settings saved");
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	const begin2fa = async () => {
		try {
			setSetup(await authApi.setup2fa());
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};
	const confirm2fa = async () => {
		try {
			await authApi.enable2fa(totp);
			toast.success("2FA enabled");
			setSetup(null);
			setTotp("");
			refresh();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Invalid code");
		}
	};
	const disable2fa = async () => {
		try {
			await authApi.disable2fa(disablePw);
			toast.success("2FA disabled");
			setDisable2faOpen(false);
			setDisablePw("");
			refresh();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	const deleteAccount = async () => {
		try {
			await account.deleteAccount(deletePw);
			toast.success("Account deleted");
			navigate("/login", { replace: true });
			window.location.reload();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	return (
		<div>
			<PageHeader title="Settings" subtitle="Manage your account, security, and data." />

			<div className="grid gap-5 lg:grid-cols-2">
				<Section title="Profile">
					<div className="space-y-3">
						<Input label="Username" value={user?.username ?? ""} disabled />
						<Input label="Display name" value={displayName} onChange={(e) => setDisplayName(e.target.value)} />
						<Button onClick={saveProfile}>Save profile</Button>
					</div>
				</Section>

				<Section title="Password">
					<div className="space-y-3">
						<Input
							label="Current password"
							type="password"
							value={curPw}
							onChange={(e) => setCurPw(e.target.value)}
						/>
						<Input
							label="New password"
							type="password"
							value={newPw}
							onChange={(e) => setNewPw(e.target.value)}
							hint="At least 8 characters."
						/>
						<Button onClick={savePassword} disabled={!curPw || newPw.length < 8}>
							Change password
						</Button>
					</div>
				</Section>

				<Section title="Two-factor authentication" description="Add a TOTP authenticator app for extra security.">
					{user?.totp_enabled ? (
						<div className="flex flex-wrap items-center justify-between gap-3">
							<span className="text-sm text-approved">✓ 2FA is enabled</span>
							<Button variant="danger" onClick={() => setDisable2faOpen(true)}>
								Disable
							</Button>
						</div>
					) : setup ? (
						<div className="space-y-3">
							<p className="text-sm text-muted">
								Add this secret to your authenticator app, then enter the 6-digit code.
							</p>
							<CodeBlock code={setup.secret} />
							<Input
								label="Authenticator code"
								value={totp}
								onChange={(e) => setTotp(e.target.value.replace(/\D/g, "").slice(0, 6))}
								placeholder="123456"
								inputMode="numeric"
							/>
							<div className="flex gap-2">
								<Button onClick={confirm2fa} disabled={totp.length !== 6}>
									Enable 2FA
								</Button>
								<Button variant="ghost" onClick={() => setSetup(null)}>
									Cancel
								</Button>
							</div>
						</div>
					) : (
						<Button onClick={begin2fa}>Set up 2FA</Button>
					)}
				</Section>

				<Section
					title="Auto-delete old requests"
					description="Disabled by default. When on, requests older than the retention window are permanently deleted (minimum 7 days)."
				>
					<div className="space-y-4">
						<Toggle checked={autoDelete} onChange={(v) => saveAutoDelete(v, autoDeleteDays)} label="Enable auto-delete" />
						{autoDelete && (
							<div>
								<div className="mb-1 flex items-center justify-between text-sm">
									<span className="text-muted">Retention window</span>
									<span className="font-medium text-text">{autoDeleteDays} days</span>
								</div>
								<input
									type="range"
									min={7}
									max={90}
									value={autoDeleteDays}
									onChange={(e) => setAutoDeleteDays(Number(e.target.value))}
									onMouseUp={() => saveAutoDelete(true, autoDeleteDays)}
									onTouchEnd={() => saveAutoDelete(true, autoDeleteDays)}
									className="w-full accent-[var(--color-primary)]"
								/>
							</div>
						)}
					</div>
				</Section>

				<Section title="Export your data" description="Download all your data (account, agents, requests, notifications) as JSON.">
					<a href={account.exportUrl} download>
						<Button variant="secondary">Download export</Button>
					</a>
				</Section>

				<Section title="Danger zone" description="Permanently delete your account and all associated data. This cannot be undone.">
					<Button variant="danger" onClick={() => setDeleteOpen(true)}>
						Delete account
					</Button>
				</Section>
			</div>

			<Modal
				open={disable2faOpen}
				onClose={() => setDisable2faOpen(false)}
				onSubmit={disable2fa}
				title="Disable 2FA"
				footer={
					<>
						<Button variant="ghost" onClick={() => setDisable2faOpen(false)}>
							Cancel
						</Button>
						<Button variant="danger" onClick={disable2fa}>
							Disable
						</Button>
					</>
				}
			>
				<Input
					label="Confirm your password"
					type="password"
					value={disablePw}
					onChange={(e) => setDisablePw(e.target.value)}
				/>
			</Modal>

			<Modal
				open={deleteOpen}
				onClose={() => setDeleteOpen(false)}
				onSubmit={deleteAccount}
				title="Delete account"
				footer={
					<>
						<Button variant="ghost" onClick={() => setDeleteOpen(false)}>
							Cancel
						</Button>
						<Button variant="danger" onClick={deleteAccount} disabled={!deletePw}>
							Permanently delete
						</Button>
					</>
				}
			>
				<div className="space-y-3">
					<p className="text-sm text-muted">
						This deletes your account and cascades to all your agents, change requests, and notifications.
						This action is irreversible.
					</p>
					<Input
						label="Confirm your password"
						type="password"
						value={deletePw}
						onChange={(e) => setDeletePw(e.target.value)}
					/>
				</div>
			</Modal>
		</div>
	);
}
