import {useCallback, useEffect, useState} from "react";
import {Link, useNavigate} from "react-router-dom";
import {ArrowRight, CheckCircle2, Command, Eye, EyeOff, Loader2, ShieldAlert} from "lucide-react";
import {toast} from "sonner";
import {apiAuthCaptcha, apiAuthRegister, type ApiResponseCaptchaResponse} from "@/client";
import {getApiErrorMessage} from "@/lib/api-error";
import {AuthLayout} from "@/components/auth/auth-layout";
import {Button} from "@/components/ui/button";
import {Input} from "@/components/ui/input";
import {rsaEncrypt} from "@/lib/rsa";
import {AnimatePresence, motion} from "framer-motion";

export function RegisterPage() {
    const navigate = useNavigate();

    const [form, setForm] = useState({
        email: "",
        username: "",
        password: "",
        confirmPassword: "",
        captcha: "",
    });
    const [showPassword, setShowPassword] = useState(false);
    const [isLoading, setIsLoading] = useState(false);
    const [captcha, setCaptcha] = useState<ApiResponseCaptchaResponse['data'] | null>(null);
    const [captchaLoading, setCaptchaLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const loadCaptcha = useCallback(async () => {
        setCaptchaLoading(true);
        try {
            const resp = await apiAuthCaptcha({body: {w: 100, h: 32, dark: false, rsa: true}});
            if (resp.data?.data) setCaptcha(resp.data.data);
        } catch { /* non-critical */
        } finally {
            setCaptchaLoading(false);
        }
    }, []);

    useEffect(() => {
        loadCaptcha();
    }, [loadCaptcha]);

    const validate = () => {
        if (!form.email.trim()) return "Email is required";
        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) return "Invalid email address";
        if (!form.username.trim()) return "Username is required";
        if (form.username.length < 3) return "Username must be at least 3 characters";
        if (!form.password) return "Password is required";
        if (form.password.length < 8) return "Password must be at least 8 characters";
        if (!/[A-Z]/.test(form.password) || !/[a-z]/.test(form.password) || !/[0-9]/.test(form.password)) {
            return "Password must include uppercase, lowercase, and a digit";
        }
        if (form.password !== form.confirmPassword) return "Passwords do not match";
        if (!form.captcha.trim()) return "Verification code is required";
        return null;
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        const validationError = validate();
        if (validationError) {
            setError(validationError);
            return;
        }
        setError(null);
        setIsLoading(true);
        try {
            const encryptedPassword = captcha?.rsa
                ? rsaEncrypt(form.password, captcha.rsa.public_key)
                : form.password;

            const resp = await apiAuthRegister({
                body: {
                    username: form.username,
                    email: form.email,
                    password: encryptedPassword,
                    captcha: form.captcha,
                },
            });

            if (resp.data?.code !== 0) {
                throw new Error(resp.data?.message || "Registration failed");
            }

            toast.success("Account created successfully!");
            navigate("/auth/login");
        } catch (err: any) {
            const msg = getApiErrorMessage(err, "Registration failed");
            setError(msg);
            toast.error(msg);
            await loadCaptcha();
            setForm((p) => ({...p, captcha: ""}));
        } finally {
            setIsLoading(false);
        }
    };

    const set = (key: keyof typeof form) => (e: React.ChangeEvent<HTMLInputElement>) => {
        setForm((p) => ({...p, [key]: e.target.value}));
        if (error) setError(null); // 输入时清除错误提示
    };

    return (
        <AuthLayout>
            <motion.div
                initial={{opacity: 0, y: 10}}
                animate={{opacity: 1, y: 0}}
                transition={{duration: 0.4}}
                className="w-full max-w-[420px] mx-auto py-8"
            >
                {/* 头部区域 */}
                <div className="flex flex-col items-center text-center mb-8 space-y-3">
                    <div
                        className="h-12 w-12 bg-zinc-900 dark:bg-zinc-100 rounded-2xl flex items-center justify-center shadow-sm">
                        <Command className="h-6 w-6 text-white dark:text-zinc-900"/>
                    </div>
                    <div>
                        <h1 className="text-2xl font-semibold tracking-tight text-zinc-900 dark:text-zinc-100">
                            Create an account
                        </h1>
                        <p className="mt-1.5 text-sm text-zinc-500 dark:text-zinc-400">
                            Join the next generation of human-agent collaboration
                        </p>
                    </div>
                </div>

                {/* 表单卡片 */}
                <div
                    className="bg-white dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800/80 rounded-3xl p-6 md:p-8 shadow-[0_8px_30px_rgb(0,0,0,0.02)] dark:shadow-none">
                    <form onSubmit={handleSubmit} className="space-y-4">

                        {/* Email */}
                        <div className="space-y-1.5">
                            <label htmlFor="email"
                                   className="text-sm font-medium text-zinc-700 dark:text-zinc-300 ml-0.5">
                                Email
                            </label>
                            <Input
                                id="email"
                                type="email"
                                placeholder="name@company.com"
                                value={form.email}
                                onChange={set("email")}
                                className="h-10 bg-zinc-50/50 dark:bg-zinc-900/50 border-zinc-200 dark:border-zinc-800 rounded-xl focus-visible:ring-1 focus-visible:ring-zinc-400"
                                disabled={isLoading}
                            />
                        </div>

                        {/* Username */}
                        <div className="space-y-1.5">
                            <label htmlFor="username"
                                   className="text-sm font-medium text-zinc-700 dark:text-zinc-300 ml-0.5">
                                Username
                            </label>
                            <Input
                                id="username"
                                type="text"
                                placeholder="architect_01"
                                value={form.username}
                                onChange={set("username")}
                                className="h-10 bg-zinc-50/50 dark:bg-zinc-900/50 border-zinc-200 dark:border-zinc-800 rounded-xl focus-visible:ring-1 focus-visible:ring-zinc-400"
                                disabled={isLoading}
                            />
                        </div>

                        {/* Password */}
                        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                            <div className="space-y-1.5">
                                <label htmlFor="password"
                                       className="text-sm font-medium text-zinc-700 dark:text-zinc-300 ml-0.5">
                                    Password
                                </label>
                                <div className="relative">
                                    <Input
                                        id="password"
                                        type={showPassword ? "text" : "password"}
                                        placeholder="••••••••"
                                        value={form.password}
                                        onChange={set("password")}
                                        className="h-10 pr-9 bg-zinc-50/50 dark:bg-zinc-900/50 border-zinc-200 dark:border-zinc-800 rounded-xl focus-visible:ring-1 focus-visible:ring-zinc-400"
                                        disabled={isLoading}
                                    />
                                    <button
                                        type="button"
                                        onClick={() => setShowPassword(!showPassword)}
                                        className="absolute right-2.5 top-1/2 -translate-y-1/2 text-zinc-400 hover:text-zinc-600 transition-colors"
                                    >
                                        {showPassword ? <EyeOff className="size-4"/> : <Eye className="size-4"/>}
                                    </button>
                                </div>
                            </div>
                            <div className="space-y-1.5">
                                <label htmlFor="confirmPassword"
                                       className="text-sm font-medium text-zinc-700 dark:text-zinc-300 ml-0.5">
                                    Confirm
                                </label>
                                <Input
                                    id="confirmPassword"
                                    type={showPassword ? "text" : "password"}
                                    placeholder="••••••••"
                                    value={form.confirmPassword}
                                    onChange={set("confirmPassword")}
                                    className="h-10 bg-zinc-50/50 dark:bg-zinc-900/50 border-zinc-200 dark:border-zinc-800 rounded-xl focus-visible:ring-1 focus-visible:ring-zinc-400"
                                    disabled={isLoading}
                                />
                            </div>
                        </div>

                        {/* 验证码 - 延续登录页的内嵌精致设计 */}
                        <div className="space-y-1.5 pt-1">
                            <label htmlFor="captcha"
                                   className="text-sm font-medium text-zinc-700 dark:text-zinc-300 ml-0.5">
                                Verification
                            </label>
                            <div className="relative flex items-center">
                                <Input
                                    id="captcha"
                                    placeholder="Captcha"
                                    value={form.captcha}
                                    onChange={set("captcha")}
                                    className="h-10 pl-3 pr-[110px] bg-zinc-50/50 dark:bg-zinc-900/50 border-zinc-200 dark:border-zinc-800 rounded-xl focus-visible:ring-1 focus-visible:ring-zinc-400"
                                    disabled={isLoading || captchaLoading}
                                />
                                <button
                                    type="button"
                                    onClick={loadCaptcha}
                                    disabled={captchaLoading}
                                    className="absolute right-1 top-1 bottom-1 w-[100px] rounded-lg overflow-hidden bg-white dark:bg-zinc-800 border border-zinc-100 dark:border-zinc-700 hover:opacity-80 transition-opacity flex items-center justify-center cursor-pointer"
                                >
                                    {captchaLoading ? (
                                        <Loader2 className="size-4 animate-spin text-zinc-400"/>
                                    ) : captcha ? (
                                        <img src={captcha.base64} alt="captcha"
                                             className="h-full w-full object-cover dark:invert dark:hue-rotate-180"/>
                                    ) : null}
                                </button>
                            </div>
                        </div>

                        {/* 错误提示区域 */}
                        <AnimatePresence>
                            {error && (
                                <motion.div
                                    initial={{opacity: 0, scale: 0.98}}
                                    animate={{opacity: 1, scale: 1}}
                                    className="flex items-start gap-2 p-3 text-sm text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-950/20 border border-red-100 dark:border-red-900/30 rounded-xl"
                                >
                                    <ShieldAlert className="size-4 mt-0.5 shrink-0"/>
                                    <p>{error}</p>
                                </motion.div>
                            )}
                        </AnimatePresence>

                        {/* 提交按钮 */}
                        <Button
                            type="submit"
                            disabled={isLoading}
                            className="w-full h-11 mt-2 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 hover:bg-zinc-800 dark:hover:bg-white rounded-xl font-bold transition-all group shadow-sm"
                        >
                            {isLoading ? (
                                <Loader2 className="size-4 animate-spin"/>
                            ) : (
                                <span className="flex items-center justify-center gap-2">
                                    Create Account
                                    <ArrowRight
                                        className="size-4 opacity-70 group-hover:translate-x-0.5 transition-transform"/>
                                </span>
                            )}
                        </Button>
                    </form>
                </div>

                <div className="mt-8 text-center space-y-4">
                    <p className="text-sm text-zinc-500 dark:text-zinc-400">
                        Already have an account?{" "}
                        <Link to="/auth/login"
                              className="font-bold text-zinc-900 dark:text-zinc-100 hover:underline underline-offset-4">
                            Sign in
                        </Link>
                    </p>
                    <div className="flex items-center justify-center gap-6 opacity-40 grayscale">
                        <div
                            className="flex items-center gap-1.5 text-[10px] font-bold uppercase tracking-widest text-zinc-500">
                            <CheckCircle2 className="size-3"/> Encrypted
                        </div>
                    </div>
                </div>
            </motion.div>
        </AuthLayout>
    );
}