import React, { useEffect, useRef, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";

/* ---------- Inline SVG icons ---------- */
const I = {
    key: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><circle cx="8" cy="14" r="4.5" stroke="currentColor" strokeWidth="1.8" /><path d="M11 11l8-8M16 6l2.5 2.5M19 3l2 2" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" /></svg>),
    mail: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><rect x="3" y="5" width="18" height="14" rx="2.5" stroke="currentColor" strokeWidth="1.8" /><path d="M4 7l8 5.5L20 7" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /></svg>),
    eye: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7S2 12 2 12Z" stroke="currentColor" strokeWidth="1.8" /><circle cx="12" cy="12" r="3" stroke="currentColor" strokeWidth="1.8" /></svg>),
    eyeOff: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><path d="M3 3l18 18" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /><path d="M10.6 6.2A9.7 9.7 0 0 1 12 6c6.4 0 10 6 10 6a16 16 0 0 1-3 3.5M6.3 7.8A16 16 0 0 0 2 12s3.6 7 10 7a9.6 9.6 0 0 0 3.7-.7" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /><path d="M9.5 10.4a3 3 0 0 0 4.1 4.2" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /></svg>),
    check: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><path d="M5 12.5l4.5 4.5L19 7" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round" /></svg>),
    alert: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="1.8" /><path d="M12 7.5v5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /><circle cx="12" cy="16" r="1.1" fill="currentColor" /></svg>),
    shield: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><path d="M12 3l7 2.5v5.5c0 4.5-3 7.8-7 9-4-1.2-7-4.5-7-9V5.5L12 3Z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" /><path d="M9 12l2 2 4-4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" /></svg>),
    arrow: (p: any) => (<svg viewBox="0 0 24 24" fill="none" {...p}><path d="M5 12h13M13 6l6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /></svg>),
};

/* ---------- Ember canvas ---------- */
const EmberCanvas = () => {
    const ref = useRef<HTMLCanvasElement>(null);
    useEffect(() => {
        const canvas = ref.current;
        if (!canvas) return;
        const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
        const ctx = canvas.getContext("2d");
        if (!ctx) return;
        let w = 0, h = 0, dpr = 1, raf = 0, roRaf = 0;
        const sparks: any[] = [];

        const resize = () => {
            dpr = Math.min(window.devicePixelRatio || 1, 2);
            const r = canvas.getBoundingClientRect();
            w = r.width; h = r.height;
            canvas.width = w * dpr; canvas.height = h * dpr;
            ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
        };
        resize();
        const ro = new ResizeObserver(() => {
            cancelAnimationFrame(roRaf);
            roRaf = requestAnimationFrame(resize);
        });
        ro.observe(canvas);

        const COLORS = ["#E2540B", "#FF6A1A", "#FF7A1A", "#FF8A2B"];
        const spawn = (initial: boolean) => ({
            x: Math.random() * w,
            y: (initial ? Math.random() : 1 + Math.random() * 0.05) * h,
            r: 0.9 + Math.random() * 2.2,
            vy: 0.45 + Math.random() * 1.4,
            vx: (Math.random() - 0.5) * 0.35,
            drift: Math.random() * Math.PI * 2,
            ds: 0.01 + Math.random() * 0.02,
            life: 0,
            max: 480 + Math.random() * 480,
            c: COLORS[(Math.random() * COLORS.length) | 0],
            glow: 0.6 + Math.random() * 0.4,
        });
        const COUNT = Math.round(Math.max(90, Math.min(140, (w * h) / 3200)));
        for (let i = 0; i < COUNT; i++) sparks.push(spawn(true));

        const frame = () => {
            ctx.clearRect(0, 0, w, h);
            for (const s of sparks) {
                s.life++;
                s.drift += s.ds;
                s.y -= s.vy;
                s.x += s.vx + Math.sin(s.drift) * 0.4;
                const fade = 1 - s.life / s.max;
                if (s.y < -10 || fade <= 0) Object.assign(s, spawn(false));
                const t = s.life / s.max;
                const env = Math.max(0, Math.min(1, t * 8, (1 - t) * 5));
                ctx.beginPath();
                ctx.fillStyle = s.c;
                ctx.shadowColor = s.c;
                ctx.shadowBlur = 10;
                ctx.globalAlpha = env * s.glow;
                ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
                ctx.fill();
            }
            ctx.globalAlpha = 1; ctx.shadowBlur = 0;
            raf = requestAnimationFrame(frame);
        };
        if (!reduce) frame();
        else {
            for (const s of sparks) {
                ctx.beginPath(); ctx.fillStyle = s.c; ctx.globalAlpha = 0.5;
                ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2); ctx.fill();
            }
            ctx.globalAlpha = 1;
        }
        return () => { cancelAnimationFrame(raf); cancelAnimationFrame(roRaf); ro.disconnect(); };
    }, []);
    return <canvas ref={ref} className="lo-embers" />;
};

/* ---------- 6-digit code input ---------- */
const CodeInput = ({ value, onChange, shake }: { value: string; onChange: (v: string) => void; shake: boolean }) => {
    const refs = useRef<(HTMLInputElement | null)[]>([]);
    const set = (i: number, v: string) => {
        const d = v.replace(/\D/g, "");
        const arr = value.split("");
        if (!d) {
            arr[i] = ""; onChange(arr.join(""));
            return;
        }
        arr[i] = d[d.length - 1];
        onChange(arr.join("").slice(0, 6));
        if (i < 5) refs.current[i + 1]?.focus();
    };
    const onPaste = (e: React.ClipboardEvent) => {
        e.preventDefault();
        const d = (e.clipboardData.getData("text") || "").replace(/\D/g, "").slice(0, 6);
        if (d) { onChange(d); refs.current[Math.min(d.length, 5)]?.focus(); }
    };
    const onKey = (i: number, e: React.KeyboardEvent) => {
        if (e.key === "Backspace" && !value[i] && i > 0) refs.current[i - 1]?.focus();
        if (e.key === "ArrowLeft" && i > 0) refs.current[i - 1]?.focus();
        if (e.key === "ArrowRight" && i < 5) refs.current[i + 1]?.focus();
    };
    return (
        <div className={"lo-code-row" + (shake ? " lo-shake" : "")}>
            {Array.from({ length: 6 }).map((_, i) => (
                <input
                    key={i}
                    ref={el => (refs.current[i] = el)}
                    className={"lo-code-box" + (value[i] ? " is-filled" : "")}
                    inputMode="numeric"
                    maxLength={1}
                    value={value[i] || ""}
                    onChange={e => set(i, e.target.value)}
                    onKeyDown={e => onKey(i, e)}
                    onPaste={onPaste}
                    aria-label={`Digit ${i + 1}`}
                />
            ))}
        </div>
    );
};

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

const Login = () => {
    const [mode, setMode] = useState<"password" | "code">("password");
    const [codeStep, setCodeStep] = useState<"email" | "verify">("email");
    const [email, setEmail] = useState<string>(() => localStorage.getItem("fo_email") || "");
    const [pw, setPw] = useState("");
    const [showPw, setShowPw] = useState(false);
    const [remember, setRemember] = useState<boolean>(!!localStorage.getItem("fo_email"));
    const [code, setCode] = useState("");
    const [shakeCode, setShakeCode] = useState(false);
    const [errors, setErrors] = useState<{ email?: string; pw?: string; code?: string; form?: string }>({});
    const [loading, setLoading] = useState(false);
    const [success, setSuccess] = useState(false);
    const [resendIn, setResendIn] = useState(0);
    const navigate = useNavigate();

    useEffect(() => {
        if ($admin_id != 0) navigate("/home");
    }, [navigate]);

    useEffect(() => {
        if (resendIn <= 0) return;
        const t = setTimeout(() => setResendIn(s => s - 1), 1000);
        return () => clearTimeout(t);
    }, [resendIn]);

    const switchMode = (m: "password" | "code") => {
        if (m === mode) return;
        setMode(m);
        setErrors({});
        if (m === "code") setCodeStep("email");
    };

    const btnGlow = (e: React.MouseEvent<HTMLButtonElement>) => {
        const r = e.currentTarget.getBoundingClientRect();
        e.currentTarget.style.setProperty("--mx", `${e.clientX - r.left}px`);
    };

    const finishLogin = () => {
        if (remember) localStorage.setItem("fo_email", email);
        else localStorage.removeItem("fo_email");
        setSuccess(true);
        setTimeout(() => location.reload(), 900);
    };

    /* Password mode */
    const submitPassword = async (e: React.FormEvent) => {
        e.preventDefault();
        const errs: typeof errors = {};
        if (!email.trim()) errs.email = "Enter your studio email.";
        else if (!EMAIL_RE.test(email)) errs.email = "That doesn't look like a valid email.";
        if (!pw) errs.pw = "Enter your password.";
        setErrors(errs);
        if (Object.keys(errs).length) return;

        setLoading(true);
        try {
            const r = await axios.post("/login", { email, password: pw });
            if (r.status === 200) finishLogin();
            else { setErrors({ form: r.data.message || "Invalid email or password" }); setLoading(false); }
        } catch (err: any) {
            setErrors({ form: err.response?.data?.message || "An error occurred during login" });
            setLoading(false);
        }
    };

    /* Code mode: send code */
    const sendCode = async (e: React.FormEvent) => {
        e.preventDefault();
        const errs: typeof errors = {};
        if (!email.trim()) errs.email = "Enter your studio email.";
        else if (!EMAIL_RE.test(email)) errs.email = "That doesn't look like a valid email.";
        setErrors(errs);
        if (Object.keys(errs).length) return;

        setLoading(true);
        try {
            await axios.post("/login/code/send", { email });
            setCodeStep("verify");
            setCode("");
            setResendIn(30);
        } catch (err: any) {
            setErrors({ form: err.response?.data?.message || "Could not send the code. Try again." });
        } finally {
            setLoading(false);
        }
    };

    /* Code mode: verify code */
    const verifyCode = async (override?: string) => {
        const c = override ?? code;
        if (c.length < 6) { setErrors({ code: "Enter all 6 digits." }); return; }
        setLoading(true);
        try {
            const r = await axios.post("/login/code/verify", { email, code: c });
            if (r.status === 200) finishLogin();
            else { setErrors({ code: r.data.message || "Invalid code" }); setLoading(false); }
        } catch (err: any) {
            setErrors({ code: err.response?.data?.message || "Invalid or expired code." });
            setShakeCode(true);
            setCode("");
            setTimeout(() => setShakeCode(false), 450);
            setLoading(false);
        }
    };

    /* Auto-verify when 6 digits entered */
    useEffect(() => {
        if (mode === "code" && codeStep === "verify" && code.length === 6 && !loading) {
            const t = setTimeout(() => verifyCode(code), 250);
            return () => clearTimeout(t);
        }
    }, [code]); // eslint-disable-line

    const resendCode = async () => {
        setErrors({});
        setLoading(true);
        try {
            await axios.post("/login/code/send", { email });
            setCode("");
            setResendIn(30);
        } catch (err: any) {
            setErrors({ form: err.response?.data?.message || "Could not resend the code." });
        } finally {
            setLoading(false);
        }
    };

    return (
        <div className="lo-stage">
            <div className="lo-frame">
                <aside className="lo-panel">
                    <EmberCanvas />
                    <div className="lo-owl-emblem">
                        <div className="lo-owl-bob">
                            <div className="lo-owl-flutter">
                                <img className="lo-owl-img" src="/images/icon-white.png" alt="Flameowl" />
                            </div>
                        </div>
                    </div>
                    <div className="lo-panel-foot">
                        <span className="lo-secure">
                            {I.shield({ width: 14, height: 14, style: { color: "var(--ember)" } })}
                            Secured access
                        </span>
                        <span>© 2026 Flameowl Studio</span>
                    </div>
                </aside>

                <main className="lo-form-side">
                    <img className="lo-mobile-owl-bg" src="/images/icon-orange.png" alt="" aria-hidden="true" />
                    <div className="lo-form-inner">
                        <div className="lo-head">
                            <div className="lo-eyebrow"><span className="lo-dot" /> Console access</div>
                            <h2>Welcome back</h2>
                            <p>Sign in to the Flameowl Studio console.</p>
                        </div>

                        {/* Segmented toggle */}
                        <div className="lo-seg" role="tablist">
                            <div className="lo-seg-pill" style={{ transform: `translateX(${mode === "code" ? "100%" : "0"})` }} />
                            <button type="button" className={mode === "password" ? "is-active" : ""} onClick={() => switchMode("password")} role="tab">
                                {I.key({ width: 15, height: 15 })} Password
                            </button>
                            <button type="button" className={mode === "code" ? "is-active" : ""} onClick={() => switchMode("code")} role="tab">
                                {I.mail({ width: 15, height: 15 })} Login code
                            </button>
                        </div>

                        {/* PASSWORD MODE */}
                        {mode === "password" && (
                            <form className="lo-fade-key lo-stagger" key="pw" onSubmit={submitPassword} noValidate>
                                <div className="lo-field">
                                    <label htmlFor="lo-email">Studio email</label>
                                    <div className="lo-input-wrap">
                                        <input id="lo-email" type="email" autoComplete="username"
                                            className={"lo-input" + (errors.email ? " is-error" : "")}
                                            placeholder="you@flameowlstudio.com"
                                            value={email}
                                            onChange={e => { setEmail(e.target.value); if (errors.email) setErrors(x => ({ ...x, email: undefined })); }} />
                                    </div>
                                    {errors.email && <div className="lo-field-err">{I.alert({ width: 14, height: 14 })} {errors.email}</div>}
                                </div>

                                <div className="lo-field">
                                    <label htmlFor="lo-pw">Password</label>
                                    <div className="lo-input-wrap">
                                        <input id="lo-pw" type={showPw ? "text" : "password"} autoComplete="current-password"
                                            className={"lo-input lo-has-btn" + (errors.pw ? " is-error" : "")}
                                            placeholder="Enter your password"
                                            value={pw}
                                            onChange={e => { setPw(e.target.value); if (errors.pw) setErrors(x => ({ ...x, pw: undefined })); }} />
                                        <button type="button" className="lo-eye" onClick={() => setShowPw(s => !s)} aria-label={showPw ? "Hide password" : "Show password"}>
                                            {showPw ? I.eyeOff({ width: 19, height: 19 }) : I.eye({ width: 19, height: 19 })}
                                        </button>
                                    </div>
                                    {errors.pw && <div className="lo-field-err">{I.alert({ width: 14, height: 14 })} {errors.pw}</div>}
                                </div>

                                <div className="lo-row-between">
                                    <label className="lo-check">
                                        <input type="checkbox" checked={remember} onChange={e => setRemember(e.target.checked)} />
                                        <span className="lo-box">{I.check({})}</span>
                                        <span className="lo-lbl">Remember me</span>
                                    </label>
                                </div>

                                {errors.form && (
                                    <div className="lo-form-err">{I.alert({ width: 15, height: 15 })}<span>{errors.form}</span></div>
                                )}

                                <button className="lo-btn" type="submit" disabled={loading} onMouseMove={btnGlow}>
                                    {loading
                                        ? <><span className="lo-spinner" /> Signing in…</>
                                        : <>Sign in {I.arrow({ width: 18, height: 18, className: "lo-arr" })}</>}
                                </button>
                            </form>
                        )}

                        {/* CODE MODE — step 1 */}
                        {mode === "code" && codeStep === "email" && (
                            <form className="lo-fade-key lo-stagger" key="code-email" onSubmit={sendCode} noValidate>
                                <div className="lo-field">
                                    <label htmlFor="lo-cemail">Studio email</label>
                                    <div className="lo-input-wrap">
                                        <input id="lo-cemail" type="email" autoComplete="username"
                                            className={"lo-input" + (errors.email ? " is-error" : "")}
                                            placeholder="you@flameowlstudio.com"
                                            value={email}
                                            onChange={e => { setEmail(e.target.value); if (errors.email) setErrors(x => ({ ...x, email: undefined })); }} />
                                    </div>
                                    {errors.email && <div className="lo-field-err">{I.alert({ width: 14, height: 14 })} {errors.email}</div>}
                                </div>
                                <p className="lo-helper">We'll email you a 6-digit code to sign in — no password needed.</p>

                                <div className="lo-row-between">
                                    <label className="lo-check">
                                        <input type="checkbox" checked={remember} onChange={e => setRemember(e.target.checked)} />
                                        <span className="lo-box">{I.check({})}</span>
                                        <span className="lo-lbl">Remember me</span>
                                    </label>
                                </div>

                                {errors.form && (
                                    <div className="lo-form-err">{I.alert({ width: 15, height: 15 })}<span>{errors.form}</span></div>
                                )}

                                <button className="lo-btn" type="submit" disabled={loading} onMouseMove={btnGlow}>
                                    {loading
                                        ? <><span className="lo-spinner" /> Sending code…</>
                                        : <>Email me a login code {I.arrow({ width: 18, height: 18, className: "lo-arr" })}</>}
                                </button>
                            </form>
                        )}

                        {/* CODE MODE — step 2 */}
                        {mode === "code" && codeStep === "verify" && (
                            <form className="lo-fade-key" key="code-verify" onSubmit={e => { e.preventDefault(); verifyCode(); }} noValidate>
                                <p className="lo-sent-to">Enter the code we sent to <b>{email}</b></p>
                                <CodeInput value={code} onChange={v => { setCode(v); if (errors.code) setErrors(x => ({ ...x, code: undefined })); }} shake={shakeCode} />
                                {errors.code && <div className="lo-field-err" style={{ marginBottom: 14 }}>{I.alert({ width: 14, height: 14 })} {errors.code}</div>}

                                <button className="lo-btn" type="submit"
                                    disabled={loading || code.length < 6}
                                    onMouseMove={btnGlow}
                                    style={{ marginTop: 14 }}>
                                    {loading
                                        ? <><span className="lo-spinner" /> Verifying…</>
                                        : <>Verify &amp; sign in {I.arrow({ width: 18, height: 18, className: "lo-arr" })}</>}
                                </button>

                                <div className="lo-resend">
                                    {resendIn > 0
                                        ? <>Resend code in {resendIn}s</>
                                        : <>Didn't get it? <button type="button" className="lo-link" onClick={resendCode}>Resend code</button></>}
                                    <span> · </span>
                                    <button type="button" className="lo-link" onClick={() => { setCodeStep("email"); setCode(""); setErrors({}); }}>Change email</button>
                                </div>
                            </form>
                        )}

                        <div className="lo-form-foot">
                            Need access? Contact your studio administrator.
                        </div>
                    </div>

                    {success && (
                        <div className="lo-success">
                            <div className="lo-ring"><img src="/images/icon-orange.png" alt="" /></div>
                            <h3>Access granted</h3>
                            <p>{I.check({ width: 16, height: 16, style: { color: "var(--ok)" } })} Welcome back to the roost</p>
                        </div>
                    )}
                </main>
            </div>
        </div>
    );
};

export default Login;
