import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { AlertTriangle, Check, Clock, LogIn, ShieldCheck, X } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { AuthShell } from "../features/auth/AuthShell";
import { loginRedirect } from "../features/auth/auth";
import { stashLinkReturn } from "../features/qr/returnTo";
import { isDesktop, startDesktopLogin } from "../net/desktop";
import {
    qrApprove, qrDeny, qrRequest,
    type QrPersist, type QrRequestInfo,
} from "../net/qr";
import { useAppStore } from "../store";
import { t } from "../i18n";
import { DeviceTypeIcon, type DeviceKind } from "../ui/glyphs";
import { Button, Callout } from "../ui/primitives";
import s from "./link.module.css";

// 批准页：手机扫码后落地，确认「是哪台设备、从哪来、给什么权限」。要求已登录。
export const Route = createFileRoute("/link")({
    component: LinkApprovePage,
    validateSearch: (search: Record<string, unknown>) =>
    ({
        r: typeof search.r === "string" ? search.r : undefined,
        c: typeof search.c === "string" ? search.c : undefined,
        // p：信任时长选择（persist/once）。step-up 整页跳转回来后据此恢复，避免选择丢失。
        p: typeof search.p === "string" ? search.p : undefined,
    }),
});

type Outcome = "approved" | "denied" | "expired" | "error" | null;

function LinkApprovePage()
{
    const navigate = useNavigate();
    const { r: requestId, c: code, p: persistParam } = Route.useSearch();
    const user = useAppStore((s) => s.user);

    const [ info, setInfo ] = useState<QrRequestInfo | null>(null);
    const [ loadError, setLoadError ] = useState<string | null>(null);
    // 初值优先取 URL 的 p（step-up 跳转回来后恢复选择），否则默认更安全的「仅此次」
    // （受限访客）——避免一路默认到完整会话（full）。
    const [ persist, setPersist ] = useState<QrPersist>(persistParam === "persist" ? "persist" : "once");
    const [ submitting, setSubmitting ] = useState(false);
    const [ outcome, setOutcome ] = useState<Outcome>(null);
    const [ actionError, setActionError ] = useState<string | null>(null);

    // 未登录：暂存当前 URL 后走 broker 全局 SSO 登录，登录后由首页 beforeLoad 弹回这里。
    const handleSignIn = useCallback(async () =>
    {
        stashLinkReturn(window.location.pathname + window.location.search);
        try
        {
            if (isDesktop())
            {
                await startDesktopLogin();
                navigate({ to: "/" });
            }
            else { loginRedirect(); }
        }
        catch (e) { setLoadError(e instanceof Error ? e.message : String(e)); }
    }, [ navigate ]);

    // 已登录且参数齐全：拉取待批准设备信息。
    useEffect(() =>
    {
        if (!user || !requestId || !code) { return; }
        let cancelled = false;
        qrRequest(requestId, code).then(
            (data) =>
            {
                if (cancelled) { return; }
                setInfo(data);
                if (data.status === "expired") { setOutcome("expired"); }
                else if (data.status === "denied") { setOutcome("denied"); }
                else if (data.status === "approved") { setOutcome("approved"); }
            },
            (e) => { if (!cancelled) { setLoadError(e instanceof Error ? e.message : String(e)); } },
        );
        return () => { cancelled = true; };
    }, [ user, requestId, code ]);

    // doApprove 执行批准。step-up 二次认证已移除（full 档即可信，路由层守门）。
    const doApprove = useCallback(async () =>
    {
        if (!requestId || !code) { return; }
        setSubmitting(true);
        setActionError(null);
        try
        {
            // persist=「信任此设备」→ 完整会话（scope=full）；once=「仅此次」→ 受限访客
            // （scope=guest）。后端按 scope 经 broker 委托签发对应 tier 的会话。
            const scope = persist === "persist" ? "full" : "guest";
            await qrApprove(requestId, code, scope, persist);
            setOutcome("approved");
        }
        catch (e)
        {
            setActionError(e instanceof Error ? e.message : String(e));
        }
        finally { setSubmitting(false); }
    }, [ requestId, code, persist ]);

    // 原生客户端（非浏览器：iOS / 桌面）只接受完整权限会话——用户原则：原生 App 不允许受限
    // 访客（仅 Web / PWA 可 guest）。故批准端对原生请求强制信任时长=persist（scope=full）、
    // 隐藏「仅此次」选项，只给「信任并继续 / 拒绝」。后端 handleQRApprove 亦兜底强制。
    const requiresFull = info != null && info.deviceType !== "browser";
    useEffect(() =>
    {
        if (requiresFull) { setPersist("persist"); }
    }, [ requiresFull ]);

    // handleApprove：批准按钮，直接提交（step-up 已移除）。
    const handleApprove = async () =>
    {
        if (!requestId || !code) { return; }
        await doApprove();
    };

    const handleDeny = async () =>
    {
        if (!requestId || !code) { return; }
        setSubmitting(true);
        setActionError(null);
        try
        {
            await qrDeny(requestId, code);
            setOutcome("denied");
        }
        catch (e) { setActionError(e instanceof Error ? e.message : String(e)); }
        finally { setSubmitting(false); }
    };

    // ---- 渲染分支 --------------------------------------------------------

    if (!requestId || !code)
    {
        return (
            <AuthShell title={t("qr.approve.title")} hideBrand skipAutospace>
                <Callout tone="error" icon={<AlertTriangle size={16} />}>
                    {t("qr.approve.badLink")}
                </Callout>
                <Button variant="secondary" size="lg" block onClick={() => navigate({ to: "/" })}>
                    {t("qr.approve.backHome")}
                </Button>
            </AuthShell>
        );
    }

    if (!user)
    {
        return (
            <AuthShell
                title={t("qr.approve.title")}
                subtitle={t("qr.approve.signInFirst")}
                hideBrand
                skipAutospace
            >
                <Button
                    variant="primary"
                    size="lg"
                    block
                    leftIcon={<LogIn size={16} />}
                    onClick={() => { void handleSignIn(); }}
                >
                    {t("login.prod.button")}
                </Button>
            </AuthShell>
        );
    }

    if (outcome) { return <OutcomeView outcome={outcome} onHome={() => navigate({ to: "/" })} />; }

    if (loadError)
    {
        return (
            <AuthShell title={t("qr.approve.title")} hideBrand skipAutospace>
                <Callout tone="error" icon={<AlertTriangle size={16} />}>{loadError}</Callout>
                <Button variant="secondary" size="lg" block onClick={() => navigate({ to: "/" })}>
                    {t("qr.approve.backHome")}
                </Button>
            </AuthShell>
        );
    }

    if (!info)
    {
        return (
            <AuthShell title={t("qr.approve.title")} subtitle={t("qr.approve.loading")} hideBrand skipAutospace />
        );
    }

    return (
        <AuthShell title={t("qr.approve.title")} subtitle={t("qr.approve.subtitle")} hideBrand skipAutospace>
            {/* 待批准设备：单行身份块——图标 + 名字 + 来源 IP（monospace 元数据）。 */}
            <div className={s.device}>
                <span className={s.deviceIcon}>
                    <DeviceTypeIcon kind={mapDeviceKind(info.deviceType)} size={24} />
                </span>
                <div className={s.deviceMeta}>
                    <span className={s.deviceName}>{info.deviceName}</span>
                    <span className={s.deviceSub}>
                        {t(`deviceType.${kindKey(info.deviceType)}` as const)}
                        <span className={s.dot}>·</span>
                        <code className={s.ip}>{info.requestIp}</code>
                    </span>
                </div>
            </div>

            {/* 信任时长：两选项分段，选中项得 accent 左色条（同 Callout / Activity 语汇）。
                原生客户端不给选择——强制完整登录，故隐藏分段，仅留下方完整权限说明。 */}
            {!requiresFull && (
                <div className={s.choices} role="radiogroup" aria-label={t("qr.approve.trustLabel")}>
                    <TrustOption
                        value="persist"
                        selected={persist === "persist"}
                        onSelect={setPersist}
                        title={t("qr.approve.trust.title")}
                        hint={t("qr.approve.trust.hint")}
                    />
                    <TrustOption
                        value="once"
                        selected={persist === "once"}
                        onSelect={setPersist}
                        title={t("qr.approve.once.title")}
                        hint={t("qr.approve.once.hint")}
                    />
                </div>
            )}

            {/* 权限范围说明：原生客户端固定完整登录；浏览器随选中项切换（信任=完整、仅此次=
                受限访客），明确告知这台设备将以什么身份登录（非装饰）。 */}
            <Callout tone="info" icon={<ShieldCheck size={16} />}>
                {requiresFull
                    ? t("qr.approve.nativeFull")
                    : persist === "persist"
                        ? t("qr.approve.scopeFull")
                        : t("qr.approve.scopeGuest")}
            </Callout>

            {actionError && (
                <Callout tone="error" icon={<AlertTriangle size={16} />}>{actionError}</Callout>
            )}

            <div className={s.actions}>
                <Button
                    variant="primary"
                    size="lg"
                    block
                    loading={submitting}
                    leftIcon={<Check size={16} />}
                    onClick={() => { void handleApprove(); }}
                >
                    {requiresFull
                        ? t("qr.approve.trustContinue")
                        : t("qr.approve.approve")}
                </Button>
                <Button
                    variant="ghost"
                    size="lg"
                    block
                    disabled={submitting}
                    leftIcon={<X size={16} />}
                    onClick={() => { void handleDeny(); }}
                >
                    {t("qr.approve.deny")}
                </Button>
            </div>
        </AuthShell>
    );
}

function TrustOption(props: {
    value: QrPersist;
    selected: boolean;
    onSelect: (v: QrPersist) => void;
    title: string;
    hint: string;
})
{
    const { value, selected, onSelect, title, hint } = props;
    return (
        <button
            type="button"
            role="radio"
            aria-checked={selected}
            className={`${s.choice} ${selected ? s.choiceOn : ""}`}
            onClick={() => onSelect(value)}
        >
            <span className={s.choiceMark} aria-hidden="true">
                {selected ? <Check size={14} /> : <Clock size={14} />}
            </span>
            <span className={s.choiceText}>
                <span className={s.choiceTitle}>{title}</span>
                <span className={s.choiceHint} data-jz-level="paragraph">{hint}</span>
            </span>
        </button>
    );
}

function OutcomeView(props: { outcome: Exclude<Outcome, null>; onHome: () => void })
{
    const { outcome, onHome } = props;
    const map = {
        approved: { tone: "ok" as const, icon: <ShieldCheck size={16} />,
                    title: t("qr.approve.doneApprovedTitle"), body: t("qr.approve.doneApproved") },
        denied:   { tone: "warn" as const, icon: <X size={16} />,
                    title: t("qr.approve.doneDeniedTitle"), body: t("qr.approve.doneDenied") },
        expired:  { tone: "warn" as const, icon: <Clock size={16} />,
                    title: t("qr.approve.expiredTitle"), body: t("qr.approve.expired") },
        error:    { tone: "error" as const, icon: <AlertTriangle size={16} />,
                    title: t("qr.approve.errorTitle"), body: t("qr.approve.error") },
    }[outcome];
    return (
        <AuthShell title={map.title} hideBrand skipAutospace>
            <Callout tone={map.tone} icon={map.icon}>{map.body}</Callout>
            <Button variant="secondary" size="lg" block onClick={onHome}>
                {t("qr.approve.backHome")}
            </Button>
        </AuthShell>
    );
}

// mapDeviceKind：契约 device_type → DeviceTypeIcon 的 DeviceKind（与 DeviceStrip
// 同口径；批准页独立一份，不改动既有组件）。
function mapDeviceKind(type: string): DeviceKind
{
    const v = type.toLowerCase();
    if (v === "shortcut") { return "shortcut"; }
    if (v.includes("mac") || v === "darwin") { return "macos"; }
    if (v.includes("win")) { return "windows"; }
    if (v.includes("linux")) { return "linux"; }
    if (v.includes("ios") || v.includes("iphone") || v.includes("ipad")) { return "ios"; }
    if (v.includes("android")) { return "android"; }
    return "unknown";
}

// kindKey：device_type → deviceType.* i18n key 的已知分支，未知回退 browser。
function kindKey(type: string): "browser" | "macos" | "windows" | "linux" | "ios" | "shortcut"
{
    const v = type.toLowerCase();
    if (v === "shortcut") { return "shortcut"; }
    if (v.includes("mac") || v === "darwin") { return "macos"; }
    if (v.includes("win")) { return "windows"; }
    if (v.includes("linux")) { return "linux"; }
    if (v.includes("ios") || v.includes("iphone") || v.includes("ipad")) { return "ios"; }
    return "browser";
}
