import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useAppScope } from "@/app/app-scope/AppScopeProvider.jsx";
import {
    createExternalAdminUser,
    getExternalAdminUserPermissions,
    listExternalAdminUsers,
    listExternalAdminPermissionCatalog,
    lookupExternalAdminUserTarget,
    resetExternalAdminUserPassword,
    updateExternalAdminUserPermissions,
    updateExternalAdminUserStatus,
} from "@/features/external-admin-users/api";
import { useExternalAdminUserAbilities } from "@/features/external-admin-users/permissions.js";
import { defaultPermissionSelection } from "@/features/external-admin-users/permissionSelection.js";
import {
    externalAdminUserCreateFormSchema,
    externalAdminUserLookupSchema,
    externalAdminUserPasswordFormSchema,
    externalAdminUserPermissionsFormSchema,
} from "@/features/external-admin-users/schema";
import { toPageQuery } from "@/shared/api/query";
import { parseForm } from "@/shared/forms/validation";
import { useAdminQuery } from "@/shared/hooks/useAdminQuery.js";
import { mergePaginatedItems } from "@/shared/hooks/usePaginatedQuery.js";
import { useConfirm } from "@/shared/ui/ConfirmProvider.jsx";
import { useToast } from "@/shared/ui/ToastProvider.jsx";

const pageSize = 50;
const emptyPage = { items: [], page: 1, pageSize, total: 0 };
const emptyCreateForm = () => ({ confirmPassword: "", displayUserId: "", password: "", permissions: [], username: "" });
const emptyPasswordForm = () => ({ confirmPassword: "", password: "" });
const emptyPermissionCatalog = { items: [], total: 0 };

export function useExternalAdminUsersPage() {
    const { appCode } = useAppScope();
    const abilities = useExternalAdminUserAbilities();
    const confirm = useConfirm();
    const queryClient = useQueryClient();
    const { showToast } = useToast();
    const currentAppCodeRef = useRef(appCode);
    const lookupRequestRef = useRef(0);
    const permissionRequestRef = useRef(0);

    const [keyword, setKeywordState] = useState("");
    const [status, setStatusState] = useState("");
    const [page, setPage] = useState(1);
    const [mergedPage, setMergedPage] = useState(() => ({ ...emptyPage, appCode }));
    const [createOpen, setCreateOpen] = useState(false);
    const [createForm, setCreateFormState] = useState(emptyCreateForm);
    const [targetUser, setTargetUser] = useState(null);
    const [lookupLoading, setLookupLoading] = useState(false);
    const [createPermissionsReady, setCreatePermissionsReady] = useState(false);
    const [passwordUser, setPasswordUser] = useState(null);
    const [passwordForm, setPasswordFormState] = useState(emptyPasswordForm);
    const [actionAppCode, setActionAppCode] = useState("");
    const [loadingAction, setLoadingAction] = useState("");
    const [permissionUser, setPermissionUser] = useState(null);
    const [permissionForm, setPermissionFormState] = useState({ expectedRevision: null, permissions: [] });
    const [permissionLoading, setPermissionLoading] = useState(false);
    const [permissionError, setPermissionError] = useState("");

    const requestQuery = useMemo(
        () => toPageQuery({ keyword, page, pageSize, status }),
        [keyword, page, status],
    );
    const queryFn = useCallback(() => listExternalAdminUsers(appCode, requestQuery), [appCode, requestQuery]);
    const {
        data: queryPage = emptyPage,
        error,
        loading: queryLoading,
        reload,
    } = useAdminQuery(queryFn, {
        enabled: Boolean(appCode && abilities.canView),
        errorMessage: "加载外管用户失败",
        initialData: emptyPage,
        queryKey: ["external-admin-users", appCode, requestQuery],
    });
    const catalogQueryFn = useCallback(() => listExternalAdminPermissionCatalog(appCode), [appCode]);
    const {
        data: permissionCatalog = emptyPermissionCatalog,
        error: catalogQueryError,
        loading: catalogLoading,
        reload: reloadPermissionCatalog,
    } = useAdminQuery(catalogQueryFn, {
        enabled: Boolean(appCode && abilities.canManagePermissions),
        errorMessage: "加载外管权限目录失败",
        initialData: emptyPermissionCatalog,
        queryKey: ["external-admin-permission-catalog", appCode],
        staleTime: 5 * 60 * 1000,
    });
    const catalogEmpty =
        abilities.canManagePermissions && !catalogLoading && !catalogQueryError && permissionCatalog.items.length === 0;
    const catalogError = catalogQueryError || (catalogEmpty ? "外管权限目录为空，请联系管理员" : "");

    useLayoutEffect(() => {
        // 写操作完成回调依赖最新租户；布局 effect 在用户能继续交互前同步边界，又不在渲染阶段读写 ref。
        currentAppCodeRef.current = appCode;
    }, [appCode]);

    useEffect(() => {
        // App 是外管账号的租户边界；切换后必须立即丢弃账号、密码和用户匹配结果，禁止跨 App 复用敏感表单。
        lookupRequestRef.current += 1;
        permissionRequestRef.current += 1;
        setCreateOpen(false);
        setCreateFormState(emptyCreateForm());
        setCreatePermissionsReady(false);
        setTargetUser(null);
        setLookupLoading(false);
        setPasswordUser(null);
        setPasswordFormState(emptyPasswordForm());
        setActionAppCode("");
        setLoadingAction("");
        setPermissionUser(null);
        setPermissionFormState({ expectedRevision: null, permissions: [] });
        setPermissionLoading(false);
        setPermissionError("");
        setKeywordState("");
        setStatusState("");
        setPage(1);
        setMergedPage({ ...emptyPage, appCode });
    }, [appCode]);

    useEffect(() => {
        if (
            !createOpen ||
            !abilities.canManagePermissions ||
            createPermissionsReady ||
            catalogLoading ||
            catalogError
        ) {
            return;
        }
        // 默认值完全由目录声明，避免前端把未来新增的高风险能力自动授权；即使默认集合为空，也显式保留 []。
        setCreateFormState((current) => ({
            ...current,
            permissions: defaultPermissionSelection(permissionCatalog.items || []),
        }));
        setCreatePermissionsReady(true);
    }, [
        abilities.canManagePermissions,
        catalogError,
        catalogLoading,
        createOpen,
        createPermissionsReady,
        permissionCatalog.items,
    ]);

    useEffect(() => {
        setMergedPage({ ...emptyPage, appCode });
    }, [appCode, keyword, status]);

    useEffect(() => {
        if (queryLoading) {
            return;
        }
        const nextItems = Array.isArray(queryPage?.items) ? queryPage.items : [];
        const nextPage = Number(queryPage?.page || page || 1);
        const nextPageSize = Number(queryPage?.pageSize || pageSize);
        const nextTotal = Number(queryPage?.total || 0);

        setMergedPage((current) => {
            // 即使旧 App 请求晚到，也不能进入当前表格；scope 标记同时避免 React effect 执行前闪现旧租户数据。
            if (current.appCode !== appCode || nextPage <= 1) {
                return { ...queryPage, appCode, items: nextItems, page: nextPage, pageSize: nextPageSize, total: nextTotal };
            }
            return {
                ...queryPage,
                appCode,
                items: mergePaginatedItems(current.items || [], nextItems),
                page: nextPage,
                pageSize: nextPageSize,
                total: nextTotal,
            };
        });
    }, [appCode, page, queryLoading, queryPage]);

    const data = mergedPage.appCode === appCode ? mergedPage : { ...emptyPage, appCode };
    const loading = queryLoading && data.items.length === 0;

    const setKeyword = (value) => {
        setKeywordState(value);
        setPage(1);
    };
    const setStatus = (value) => {
        setStatusState(value);
        setPage(1);
    };
    const resetFilters = () => {
        setKeywordState("");
        setStatusState("");
        setPage(1);
    };

    const setCreateForm = (patch) => {
        if (Object.prototype.hasOwnProperty.call(patch, "permissions")) {
            setCreatePermissionsReady(true);
        }
        setCreateFormState((current) => ({ ...current, ...patch }));
    };
    const changeDisplayUserId = (value) => {
        lookupRequestRef.current += 1;
        setCreateForm({ displayUserId: value });
        setTargetUser(null);
        setLookupLoading(false);
    };
    const openCreate = () => {
        lookupRequestRef.current += 1;
        const catalogReady = !catalogLoading && !catalogError;
        setCreateFormState({
            ...emptyCreateForm(),
            permissions:
                abilities.canManagePermissions && catalogReady
                    ? defaultPermissionSelection(permissionCatalog.items || [])
                    : [],
        });
        setCreatePermissionsReady(!abilities.canManagePermissions || catalogReady);
        setTargetUser(null);
        setLookupLoading(false);
        setActionAppCode(appCode);
        setCreateOpen(true);
    };
    const closeCreate = () => {
        if (loadingAction === "create") {
            return;
        }
        lookupRequestRef.current += 1;
        setCreateOpen(false);
        setCreateFormState(emptyCreateForm());
        setCreatePermissionsReady(false);
        setTargetUser(null);
        setLookupLoading(false);
        setActionAppCode("");
    };

    const lookupTarget = async () => {
        let displayUserId;
        try {
            ({ displayUserId } = parseForm(externalAdminUserLookupSchema, createForm));
        } catch (err) {
            showToast(err.message || "请输入用户短 ID / 靓号", "error");
            return;
        }
        const scope = appCode;
        const requestId = lookupRequestRef.current + 1;
        lookupRequestRef.current = requestId;
        setLookupLoading(true);
        setTargetUser(null);
        try {
            const result = await lookupExternalAdminUserTarget(scope, displayUserId);
            if (currentAppCodeRef.current === scope && lookupRequestRef.current === requestId) {
                setTargetUser(result);
            }
        } catch (err) {
            if (currentAppCodeRef.current === scope && lookupRequestRef.current === requestId) {
                showToast(err.message || "查询 App 用户失败", "error");
            }
        } finally {
            if (currentAppCodeRef.current === scope && lookupRequestRef.current === requestId) {
                setLookupLoading(false);
            }
        }
    };

    const refreshList = useCallback(
        async (scope) => {
            if (currentAppCodeRef.current !== scope) {
                return;
            }
            setPage(1);
            setMergedPage({ ...emptyPage, appCode: scope });
            await queryClient.invalidateQueries({ queryKey: ["external-admin-users", scope] });
        },
        [queryClient],
    );

    const submitCreate = async (event) => {
        event.preventDefault();
        const scope = actionAppCode;
        if (!abilities.canCreate) {
            showToast("没有创建外管用户的权限", "error");
            return;
        }
        if (!scope || scope !== appCode) {
            showToast("应用已切换，请重新创建", "error");
            return;
        }
        if (!targetUser?.userId) {
            showToast("请先搜索并确认 App 用户", "error");
            return;
        }
        if (targetUser.existingExternalAdminUser) {
            showToast("该 App 用户已绑定外管账号", "error");
            return;
        }
        if (catalogLoading || catalogError || permissionCatalog.items.length === 0) {
            showToast(catalogError || "外管权限目录尚未加载", "error");
            return;
        }
        let formPayload;
        try {
            formPayload = parseForm(externalAdminUserCreateFormSchema, createForm);
        } catch (err) {
            showToast(err.message || "创建参数不正确", "error");
            return;
        }

        setLoadingAction("create");
        try {
            await createExternalAdminUser(scope, {
                password: formPayload.password,
                // 创建权限已收口为 create + permissions，始终提交显式快照，[] 表示主动创建零权限账号。
                permissions: formPayload.permissions || [],
                // 始终提交查询接口返回的稳定 userId，短 ID / 靓号只用于定位，避免后续改号造成错误绑定。
                targetUserId: targetUser.userId,
                username: formPayload.username,
            });
            if (currentAppCodeRef.current !== scope) {
                return;
            }
            setCreateOpen(false);
            setCreateFormState(emptyCreateForm());
            setCreatePermissionsReady(false);
            setTargetUser(null);
            setActionAppCode("");
            showToast("外管用户已创建", "success");
            await refreshList(scope);
        } catch (err) {
            if (currentAppCodeRef.current === scope) {
                showToast(err.message || "创建外管用户失败", "error");
            }
        } finally {
            if (currentAppCodeRef.current === scope) {
                setLoadingAction("");
            }
        }
    };

    const toggleStatus = async (item) => {
        const scope = appCode;
        const nextStatus = item.status === "active" ? "disabled" : "active";
        const actionLabel = nextStatus === "active" ? "启用" : "停用";
        const ok = await confirm({
            confirmText: actionLabel,
            message: `${item.username || item.id} 的外管登录权限会立即${nextStatus === "active" ? "恢复" : "失效"}。`,
            title: `${actionLabel}外管用户`,
            tone: nextStatus === "active" ? "primary" : "danger",
        });
        if (!ok || currentAppCodeRef.current !== scope) {
            return;
        }

        setLoadingAction(`status:${item.id}`);
        try {
            await updateExternalAdminUserStatus(scope, item.id, nextStatus);
            if (currentAppCodeRef.current !== scope) {
                return;
            }
            showToast(`外管用户已${actionLabel}`, "success");
            await refreshList(scope);
        } catch (err) {
            if (currentAppCodeRef.current === scope) {
                showToast(err.message || `${actionLabel}外管用户失败`, "error");
            }
        } finally {
            if (currentAppCodeRef.current === scope) {
                setLoadingAction("");
            }
        }
    };

    const openPassword = (item) => {
        setPasswordUser(item);
        setPasswordFormState(emptyPasswordForm());
        setActionAppCode(appCode);
    };
    const closePassword = () => {
        if (loadingAction.startsWith("password:")) {
            return;
        }
        setPasswordUser(null);
        setPasswordFormState(emptyPasswordForm());
        setActionAppCode("");
    };
    const setPasswordForm = (patch) => {
        setPasswordFormState((current) => ({ ...current, ...patch }));
    };
    const submitPassword = async (event) => {
        event.preventDefault();
        const scope = actionAppCode;
        const item = passwordUser;
        if (!item || !scope || scope !== appCode) {
            showToast("应用已切换，请重新操作", "error");
            return;
        }
        let payload;
        try {
            payload = parseForm(externalAdminUserPasswordFormSchema, passwordForm);
        } catch (err) {
            showToast(err.message || "密码参数不正确", "error");
            return;
        }

        setLoadingAction(`password:${item.id}`);
        try {
            await resetExternalAdminUserPassword(scope, item.id, payload.password);
            if (currentAppCodeRef.current !== scope) {
                return;
            }
            setPasswordUser(null);
            setPasswordFormState(emptyPasswordForm());
            setActionAppCode("");
            showToast("外管密码已重置", "success");
            await refreshList(scope);
        } catch (err) {
            if (currentAppCodeRef.current === scope) {
                showToast(err.message || "重置外管密码失败", "error");
            }
        } finally {
            if (currentAppCodeRef.current === scope) {
                setLoadingAction("");
            }
        }
    };

    const loadPermissions = useCallback(
        async (item, scope = appCode) => {
            const requestId = permissionRequestRef.current + 1;
            permissionRequestRef.current = requestId;
            setPermissionLoading(true);
            setPermissionError("");
            try {
                const result = await getExternalAdminUserPermissions(scope, item.id);
                if (currentAppCodeRef.current !== scope || permissionRequestRef.current !== requestId) {
                    return;
                }
                setPermissionFormState({
                    // 详情和目录可能并发返回，先保留服务端快照；提交边界再按届时已加载的目录过滤。
                    expectedRevision: result.revision,
                    permissions: result.permissions,
                });
            } catch (err) {
                if (currentAppCodeRef.current === scope && permissionRequestRef.current === requestId) {
                    setPermissionError(err.message || "加载账号权限失败");
                }
            } finally {
                if (currentAppCodeRef.current === scope && permissionRequestRef.current === requestId) {
                    setPermissionLoading(false);
                }
            }
        },
        [appCode],
    );

    const openPermissions = (item) => {
        setPermissionUser(item);
        setPermissionFormState({ expectedRevision: null, permissions: [] });
        setPermissionError("");
        setActionAppCode(appCode);
        void loadPermissions(item, appCode);
    };
    const closePermissions = () => {
        if (loadingAction.startsWith("permissions:")) {
            return;
        }
        permissionRequestRef.current += 1;
        setPermissionUser(null);
        setPermissionFormState({ expectedRevision: null, permissions: [] });
        setPermissionLoading(false);
        setPermissionError("");
        setActionAppCode("");
    };
    const retryPermissions = () => {
        if (permissionUser) {
            void loadPermissions(permissionUser, actionAppCode || appCode);
        }
    };
    const setPermissions = (permissions) => {
        setPermissionFormState((current) => ({ ...current, permissions }));
    };
    const submitPermissions = async () => {
        const scope = actionAppCode;
        const item = permissionUser;
        if (!abilities.canManagePermissions) {
            showToast("没有配置外管权限的权限", "error");
            return;
        }
        if (!item || !scope || scope !== appCode) {
            showToast("应用已切换，请重新操作", "error");
            return;
        }
        if (catalogLoading || catalogError || permissionCatalog.items.length === 0) {
            showToast(catalogError || "外管权限目录尚未加载", "error");
            return;
        }
        let payload;
        try {
            payload = parseForm(externalAdminUserPermissionsFormSchema, permissionForm);
        } catch (err) {
            showToast(err.message || "权限参数不正确", "error");
            return;
        }
        const knownCodes = new Set((permissionCatalog.items || []).map((permission) => permission.code));
        const permissions = payload.permissions.filter((permission) => knownCodes.has(permission));

        setPermissionError("");
        setLoadingAction(`permissions:${item.id}`);
        try {
            // 目录是允许写入的唯一边界；被服务端下线的旧编码不应在本次编辑中重新写回。
            await updateExternalAdminUserPermissions(scope, item.id, permissions, payload.expectedRevision);
            if (currentAppCodeRef.current !== scope) {
                return;
            }
            setPermissionUser(null);
            setPermissionFormState({ expectedRevision: null, permissions: [] });
            setPermissionError("");
            setActionAppCode("");
            showToast("权限已更新，该账号需重新登录", "success");
            await refreshList(scope);
        } catch (err) {
            if (currentAppCodeRef.current === scope) {
                const message =
                    Number(err?.status) === 409
                        ? "账号权限已被更新，请重新加载"
                        : "更新外管权限失败";
                setPermissionError(message);
                showToast(message, "error");
            }
        } finally {
            if (currentAppCodeRef.current === scope) {
                setLoadingAction("");
            }
        }
    };

    return {
        abilities,
        closeCreate,
        closePassword,
        closePermissions,
        createForm,
        createOpen,
        data,
        error,
        keyword,
        loading,
        loadingAction,
        lookupLoading,
        lookupTarget,
        openCreate,
        openPassword,
        openPermissions,
        page,
        pageSize,
        passwordForm,
        passwordUser,
        permissionCatalog,
        permissionError,
        permissionForm,
        permissionLoading,
        permissionUser,
        catalogError,
        catalogLoading,
        reload,
        resetFilters,
        reloadPermissionCatalog,
        retryPermissions,
        setCreateForm,
        setDisplayUserId: changeDisplayUserId,
        setKeyword,
        setPage,
        setPasswordForm,
        setPermissions,
        setStatus,
        status,
        submitCreate,
        submitPassword,
        submitPermissions,
        targetUser,
        toggleStatus,
    };
}
