import { useCallback } from "react";
import { useAppStore } from "../stores/app-store";

interface MicButtonProps {
	onStart: () => void;
	onStop: () => void;
}

export function MicButton({ onStart, onStop }: MicButtonProps) {
	const connected = useAppStore((s) => s.connectionStatus === "connected");
	const micReady = useAppStore((s) => s.micReady);
	const recording = useAppStore((s) => s.recording);
	const pendingStart = useAppStore((s) => s.pendingStart);
	const stopping = useAppStore((s) => s.stopping);
	const weakNetwork = useAppStore((s) => s.weakNetwork);
	const isActive = recording || pendingStart || stopping;
	const disabled = !connected || !micReady || stopping;

	const handlePointerDown = useCallback(
		(e: React.PointerEvent<HTMLButtonElement>) => {
			if (e.button !== 0) return;
			e.preventDefault();
			e.currentTarget.setPointerCapture(e.pointerId);
			onStart();
		},
		[onStart],
	);

	const handlePointerUp = useCallback(
		(e: React.PointerEvent<HTMLButtonElement>) => {
			e.preventDefault();
			e.currentTarget.releasePointerCapture(e.pointerId);
			onStop();
		},
		[onStop],
	);

	// Read latest state to avoid stale closures
	const handlePointerLeave = useCallback(() => {
		const s = useAppStore.getState();
		if (s.recording || s.pendingStart) onStop();
	}, [onStop]);

	const handlePointerCancel = useCallback(() => {
		const s = useAppStore.getState();
		if (s.recording || s.pendingStart) onStop();
	}, [onStop]);

	const disabledClasses =
		"cursor-not-allowed border-edge bg-linear-to-br from-surface-hover to-surface text-fg-secondary opacity-30 shadow-[0_2px_12px_rgba(0,0,0,0.3),inset_0_1px_0_rgba(255,255,255,0.04)]";
	const activeClasses =
		"animate-mic-breathe scale-[1.06] border-accent-hover bg-accent text-white shadow-[0_0_32px_rgba(99,102,241,0.35),0_0_80px_rgba(99,102,241,0.2)]";
	const weakClasses =
		"border-amber-400 bg-linear-to-br from-amber-400/15 to-surface text-amber-200 shadow-[0_0_22px_rgba(251,191,36,0.28)]";
	const idleClasses =
		"border-edge bg-linear-to-br from-surface-hover to-surface text-fg-secondary shadow-[0_2px_12px_rgba(0,0,0,0.3),inset_0_1px_0_rgba(255,255,255,0.04)]";

	return (
		<section className="flex shrink-0 flex-col items-center gap-3.5 pt-5 pb-4">
			<div className="relative flex touch-none items-center justify-center">
				<button
					type="button"
					disabled={disabled}
					className={`relative z-1 flex size-24 cursor-pointer touch-none select-none items-center justify-center rounded-full border-2 transition-all duration-[250ms] ease-[cubic-bezier(0.4,0,0.2,1)] ${
						disabled
							? disabledClasses
							: weakNetwork
								? weakClasses
								: isActive
									? activeClasses
									: idleClasses
					}`}
					onPointerDown={handlePointerDown}
					onPointerUp={handlePointerUp}
					onPointerLeave={handlePointerLeave}
					onPointerCancel={handlePointerCancel}
					onContextMenu={(e) => e.preventDefault()}
				>
					<svg
						viewBox="0 0 24 24"
						width={48}
						height={48}
						fill="currentColor"
						aria-label="麦克风"
						role="img"
					>
						<title>{"麦克风"}</title>
						<path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z" />
						<path d="M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z" />
					</svg>
				</button>

				{/* Wave rings */}
				<div
					className="pointer-events-none absolute inset-0"
					aria-hidden="true"
				>
					{[0, 0.8, 1.6].map((delay) => (
						<span
							key={delay}
							className={`absolute inset-0 rounded-full border-[1.5px] border-accent ${
								isActive ? "animate-ring-expand" : "opacity-0"
							}`}
							style={isActive ? { animationDelay: `${delay}s` } : undefined}
						/>
					))}
				</div>
			</div>
			<p className="font-medium text-fg-dim text-sm">
				{!micReady
					? "请先准备麦克风"
					: !connected
						? "连接中断，等待重连"
						: stopping
							? "收尾中…"
							: weakNetwork
								? "网络波动，已启用缓冲"
								: "按住说话"}
			</p>
		</section>
	);
}
