import { useEffect, useMemo, useState } from "react";
import { downloadResponse } from "@/shared/api/download";
import { parseForm } from "@/shared/forms/validation";
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
import { useRegionOptions } from "@/shared/hooks/useRegionOptions.js";
import { useConfirm } from "@/shared/ui/ConfirmProvider.jsx";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import { emptyUserIdentityFilter, userIdentityFilterParams } from "@/shared/ui/userIdentityFilter.js";
import {
    adjustAppUserLevels,
    banAppUser,
    createAppUserExport,
    downloadAppUserExport,
    getAppUserExportJob,
    listAppUsers,
    setAppUserPassword,
    unbanAppUser,
    updateAppUser,
} from "@/features/app-users/api";
import { useAppUserAbilities } from "@/features/app-users/permissions.js";
import {
    appUserBanSchema,
    appUserCountrySchema,
    appUserLevelAdjustmentSchema,
    appUserPasswordSchema,
    appUserUpdateSchema,
} from "@/features/app-users/schema";
import { useCountryOptions } from "@/features/host-org/hooks/useCountryOptions.js";

const pageSize = 50;
const emptyData = { items: [], page: 1, pageSize, total: 0 };
const emptyEditForm = () => ({ avatar: "", gender: "", username: "" });
const emptyCountryForm = () => ({ country: "" });
const emptyPasswordForm = () => ({ password: "" });
const emptyBanForm = () => ({ expiresAtLocal: futureDateTimeLocal(7), mode: "permanent", reason: "" });

export function useAppUsersPage() {
    const abilities = useAppUserAbilities();
    const confirm = useConfirm();
    const { showToast } = useToast();
    const { countryOptions, loadingCountries } = useCountryOptions();
    const { loadingRegions, regionOptions } = useRegionOptions();
    const [country, setCountry] = useState("");
    const [userFilter, setUserFilter] = useState(emptyUserIdentityFilter);
    const [regionId, setRegionId] = useState("");
    const [status, setStatus] = useState("");
    const [timeRange, setTimeRange] = useState({ endMs: "", startMs: "" });
    const [sortBy, setSortBy] = useState("created_at");
    const [sortDirection, setSortDirection] = useState("desc");
    const [page, setPage] = useState(1);
    const [activeAction, setActiveAction] = useState("");
    const [activeUser, setActiveUser] = useState(null);
    const [editForm, setEditForm] = useState(emptyEditForm);
    const [countryForm, setCountryForm] = useState(emptyCountryForm);
    const [passwordForm, setPasswordForm] = useState(emptyPasswordForm);
    const [levelForm, setLevelForm] = useState(() => levelFormFromUser(null));
    const [banForm, setBanForm] = useState(emptyBanForm);
    const [loadingAction, setLoadingAction] = useState("");
    const [selectedUserIds, setSelectedUserIds] = useState([]);
    const [patchedUsers, setPatchedUsers] = useState({});
    const filters = useMemo(
        () => ({
            country,
            region_id: regionId,
            sort_by: sortBy,
            sort_direction: sortDirection,
            end_ms: timeRange.endMs,
            status,
            start_ms: timeRange.startMs,
            ...userIdentityFilterParams(userFilter),
        }),
        [country, regionId, sortBy, sortDirection, status, timeRange.endMs, timeRange.startMs, userFilter],
    );
    const {
        data: queryData = emptyData,
        error,
        loading,
        reload,
    } = usePaginatedQuery({
        errorMessage: "加载用户列表失败",
        fetcher: listAppUsers,
        filters,
        page,
        pageSize,
        queryKey: ["app-users", filters, page],
    });
    const data = useMemo(() => {
        const items = queryData.items || [];
        return {
            ...queryData,
            items: items.map((user) => (patchedUsers[user.userId] ? { ...user, ...patchedUsers[user.userId] } : user)),
        };
    }, [patchedUsers, queryData]);
    useEffect(() => {
        setSelectedUserIds([]);
        setPatchedUsers({});
    }, [country, page, regionId, sortBy, sortDirection, status, timeRange.endMs, timeRange.startMs, userFilter]);

    const locationFilterOptions = useMemo(() => {
        const countryItems = countryOptions.map((option) => ({
            label: `国家 · ${option.label}`,
            value: `country:${option.value}`,
        }));
        const regionItems = [
            { label: "区域 · GLOBAL · 0", value: "region:0" },
            ...regionOptions.map((option) => ({
                label: `区域 · ${option.label}`,
                value: `region:${option.value}`,
            })),
        ];
        return [...countryItems, ...regionItems];
    }, [countryOptions, regionOptions]);

    const locationFilterValue = country ? `country:${country}` : regionId !== "" ? `region:${regionId}` : "";

    const changeUserFilter = (value) => {
        setUserFilter(value);
        setPage(1);
    };

    const changeStatus = (value) => {
        setStatus(value);
        setPage(1);
    };

    const changeLocationFilter = (value) => {
        const [kind, rawValue = ""] = String(value || "").split(":");
        if (kind === "country" && rawValue) {
            setCountry(rawValue);
            setRegionId("");
        } else if (kind === "region") {
            setCountry("");
            setRegionId(rawValue);
        } else {
            setCountry("");
            setRegionId("");
        }
        setPage(1);
    };

    const changeTimeRange = (value) => {
        setTimeRange(value);
        setPage(1);
    };

    const changeSort = (field) => {
        setSortDirection((current) => (sortBy === field ? (current === "asc" ? "desc" : "asc") : "desc"));
        setSortBy(field);
        setPage(1);
    };

    const resetFilters = () => {
        setCountry("");
        setUserFilter(emptyUserIdentityFilter);
        setRegionId("");
        setStatus("");
        setTimeRange({ endMs: "", startMs: "" });
        setSortBy("created_at");
        setSortDirection("desc");
        setPage(1);
    };

    const openEdit = (user) => {
        setActiveUser(user);
        setEditForm({
            avatar: user.avatar || "",
            gender: user.gender || "",
            username: user.username || "",
        });
        setLevelForm(levelFormFromUser(user));
        setActiveAction("edit");
    };

    const openPassword = (user) => {
        setActiveUser(user);
        setPasswordForm(emptyPasswordForm());
        setActiveAction("password");
    };

    const openCountry = (user) => {
        setActiveUser(user);
        setCountryForm({ country: user.country || "" });
        setActiveAction("country");
    };

    const openCoinLedger = (user) => {
        setActiveUser(user);
        setActiveAction("coin-ledger");
    };

    const closeAction = () => {
        setActiveAction("");
        setActiveUser(null);
    };

    const submitEdit = async (event) => {
        event.preventDefault();
        if (!activeUser) {
            return;
        }
        await runAction("edit", "用户已更新", async () => {
            const payload = parseForm(appUserUpdateSchema, editForm);
            const result = await updateAppUser(activeUser.userId, payload);
            patchUsers([result]);
            setActiveUser((current) => (current ? { ...current, ...result } : result));
        });
    };

    const submitLevels = async () => {
        if (!activeUser) {
            return;
        }
        await runAction("levels", "等级调整已提交", async () => {
            const form = parseForm(appUserLevelAdjustmentSchema, levelForm);
            // 两条轨道只发一个 adjustments 数组，保证跨轨道由 activity-service 同事务提交或整体失败。
            const adjustments = ["wealth", "charm"]
                .filter((track) => form[track].enabled)
                .map((track) => ({
                    duration_days: Number(form[track].durationDays),
                    level: Number(form[track].level),
                    track,
                }));
            const result = await adjustAppUserLevels(activeUser.userId, { adjustments, reason: form.reason });
            patchUsers([result]);
            setActiveUser((current) => (current ? { ...current, ...result } : result));
            setLevelForm(levelFormFromUser(result));
        });
    };

    const submitCountry = async (event) => {
        event.preventDefault();
        if (!activeUser) {
            return;
        }
        await runAction("country", "国家已更新", async () => {
            const payload = parseForm(appUserCountrySchema, countryForm);
            await updateAppUser(activeUser.userId, payload);
            closeAction();
            await reload();
        });
    };

    const submitPassword = async (event) => {
        event.preventDefault();
        if (!activeUser) {
            return;
        }
        await runAction("password", "密码已设置", async () => {
            const payload = parseForm(appUserPasswordSchema, passwordForm);
            await setAppUserPassword(activeUser.userId, payload);
            closeAction();
        });
    };

    const toggleBan = async (user) => {
        const banned = isBanned(user);
        if (!banned) {
            setActiveUser(user);
            setBanForm(emptyBanForm());
            setActiveAction("ban");
            return;
        }
        const ok = await confirm({
            confirmText: "解封",
            message: "仅当该用户不存在其他有效管理员或经理封禁时，账号状态才会恢复。",
            title: "解封用户",
        });
        if (!ok) {
            return;
        }
        await runAction(`status-${user.userId}`, "用户已解封", async () => {
            const result = await unbanAppUser(user.userId, { reason: "admin_manual_unban" });
            patchUsers([mergeUserStatus(user, result, "active")]);
            setSelectedUserIds((current) => current.filter((userId) => userId !== user.userId));
        });
    };

    const submitBan = async (event) => {
        event.preventDefault();
        if (!activeUser) {
            return;
        }
        await runAction(`status-${activeUser.userId}`, "用户已封禁", async () => {
            const form = parseForm(appUserBanSchema, banForm);
            const expiresAtMs = form.mode === "permanent" ? 0 : new Date(form.expiresAtLocal).getTime();
            const result = await banAppUser(activeUser.userId, {
                expires_at_ms: expiresAtMs,
                reason: form.reason,
            });
            patchUsers([mergeUserStatus(activeUser, result, "banned")]);
            setSelectedUserIds((current) => current.filter((userId) => userId !== activeUser.userId));
            closeAction();
        });
    };

    const batchBan = async () => {
        const users = (data.items || []).filter((user) => selectedUserIds.includes(user.userId) && !isBanned(user));
        if (!users.length) {
            showToast("请先选择未封禁用户", "warning");
            return;
        }
        const ok = await confirm({
            confirmText: "封禁",
            message: `将永久封禁 ${users.length} 个用户。`,
            title: "批量封禁用户",
            tone: "danger",
        });
        if (!ok) {
            return;
        }

        setLoadingAction("batch-ban");
        try {
            const results = await Promise.allSettled(
                users.map((user) =>
                    banAppUser(user.userId, { expires_at_ms: 0, reason: "admin_batch_permanent_ban" }),
                ),
            );
            const updatedUsers = results
                .map((result, index) =>
                    result.status === "fulfilled" ? mergeUserStatus(users[index], result.value, "banned") : null,
                )
                .filter(Boolean);
            const failedCount = results.length - updatedUsers.length;

            if (updatedUsers.length) {
                patchUsers(updatedUsers);
                setSelectedUserIds((current) =>
                    current.filter((userId) => !updatedUsers.some((updatedUser) => updatedUser.userId === userId)),
                );
            }

            if (failedCount > 0) {
                showToast(
                    updatedUsers.length ? `已封禁 ${updatedUsers.length} 个，${failedCount} 个失败` : "批量封禁失败",
                    updatedUsers.length ? "warning" : "error",
                );
                return;
            }

            showToast(`已封禁 ${updatedUsers.length} 个用户`, "success");
        } finally {
            setLoadingAction("");
        }
    };

    const exportUsers = async () => {
        setLoadingAction("export");
        try {
            // 创建任务时仅传当前筛选快照；页码由后端固定为首批并逐页导出，避免只导出当前可见页。
            const created = await createAppUserExport(filters);
            showToast(`导出任务 #${created.jobId} 已创建`, "success");
            const job = await waitAppUserExportJob(created.jobId);
            const response = await downloadAppUserExport(created.jobId);
            await downloadResponse(response, appUserExportFilename(created.snapshotAtMs || job.createdAtMs));
            showToast("用户 CSV 已生成", "success");
        } catch (err) {
            showToast(err.message || "导出用户失败", "error");
        } finally {
            setLoadingAction("");
        }
    };

    const runAction = async (action, successMessage, submitter) => {
        setLoadingAction(action);
        try {
            await submitter();
            showToast(successMessage, "success");
        } catch (err) {
            showToast(err.message || "操作失败", "error");
        } finally {
            setLoadingAction("");
        }
    };

    const patchUsers = (users) => {
        setPatchedUsers((current) => {
            const next = { ...current };
            users.forEach((user) => {
                if (!user?.userId) {
                    return;
                }
                next[user.userId] = { ...(next[user.userId] || {}), ...user };
            });
            return next;
        });
    };

    return {
        abilities,
        activeAction,
        activeUser,
        banForm,
        batchBan,
        changeUserFilter,
        changeStatus,
        closeAction,
        changeLocationFilter,
        countryForm,
        countryOptions,
        data,
        editForm,
        error,
        loading,
        loadingAction,
        loadingCountries,
        loadingRegions,
        levelForm,
        locationFilterOptions,
        locationFilterValue,
        openCountry,
        openCoinLedger,
        openEdit,
        openPassword,
        page,
        passwordForm,
        regionId,
        regionOptions,
        reload,
        resetFilters,
        selectedUserIds,
        setCountryForm,
        setBanForm,
        setEditForm,
        setLevelForm,
        setPage,
        setPasswordForm,
        setSelectedUserIds,
        sortBy,
        sortDirection,
        status,
        timeRange,
        userFilter,
        changeSort,
        changeTimeRange,
        submitCountry,
        submitBan,
        submitEdit,
        submitLevels,
        submitPassword,
        toggleBan,
        exportUsers,
    };
}

function isBanned(user) {
    return user.status === "banned" || user.status === "disabled";
}

function mergeUserStatus(currentUser, result, fallbackStatus) {
    return {
        ...currentUser,
        ...(result || {}),
        status: result?.status || fallbackStatus,
    };
}

function levelFormFromUser(user) {
    return {
        charm: levelTrackForm(user?.levels?.charm),
        reason: "",
        wealth: levelTrackForm(user?.levels?.wealth),
    };
}

function levelTrackForm(level) {
    const realLevel = Number(level?.realLevel || 0);
    const currentTarget = Number(level?.temporaryTargetLevel || level?.displayLevel || realLevel + 1);
    const expiresAtMs = Number(level?.expiresAtMs || 0);
    const remainingDays = expiresAtMs > Date.now() ? Math.max(1, Math.ceil((expiresAtMs - Date.now()) / 86400000)) : 7;
    return {
        durationDays: String(remainingDays),
        enabled: false,
        // 旧的临时等级也要保留到产品支持的 100 级，避免打开用户资料时把有效的高等级回填成 50。
        level: String(Math.min(100, Math.max(1, currentTarget))),
    };
}

async function waitAppUserExportJob(jobId) {
    const deadline = Date.now() + 120000;
    while (Date.now() < deadline) {
        const job = await getAppUserExportJob(jobId);
        if (job.status === "succeeded") {
            return job;
        }
        if (["failed", "canceled", "cancelled"].includes(job.status)) {
            throw new Error(job.error || "用户导出任务失败");
        }
        await delay(1500);
    }
    throw new Error("用户导出任务仍在处理中，请稍后重试");
}

function delay(ms) {
    return new Promise((resolve) => {
        window.setTimeout(resolve, ms);
    });
}

function futureDateTimeLocal(days) {
    const date = new Date(Date.now() + days * 86400000);
    const offsetMs = date.getTimezoneOffset() * 60000;
    return new Date(date.getTime() - offsetMs).toISOString().slice(0, 16);
}

function appUserExportFilename(snapshotAtMs) {
    const date = new Date(Number(snapshotAtMs || Date.now()));
    const stamp = Number.isFinite(date.getTime()) ? date.toISOString().slice(0, 10) : "snapshot";
    return `app-users-${stamp}.csv`;
}
