import { useMemo, useState } from "react";
import { parseForm } from "@/shared/forms/validation";
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
import { useConfirm } from "@/shared/ui/ConfirmProvider.jsx";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import {
    createPrettyDisplayIDPool,
    generatePrettyDisplayIDs,
    grantPrettyDisplayID,
    listPrettyDisplayIDPools,
    listPrettyDisplayIDs,
    recyclePrettyDisplayID,
    setPrettyDisplayIDStatus,
    updatePrettyDisplayIDPool,
} from "@/features/app-users/api";
import { useAppUserAbilities } from "@/features/app-users/permissions.js";
import {
    prettyDisplayIDGenerateSchema,
    prettyDisplayIDGrantSchema,
    prettyDisplayIDPoolSchema,
    prettyDisplayIDStatusSchema,
} from "@/features/app-users/schema";

const pageSize = 20;
const emptyPoolForm = () => ({
    levelTrack: "wealth",
    maxLevel: 10,
    minLevel: 1,
    name: "",
    ruleConfigJson: "",
    ruleType: "aabbcc",
    sortOrder: 0,
    status: "active",
});
const emptyGenerateForm = () => ({ count: 100, poolId: "", ruleConfigJson: "", ruleType: "aabbcc" });
const emptyGrantForm = () => ({ displayUserId: "", durationDays: "", reason: "", targetUserId: "" });
const emptyStatusForm = () => ({ prettyId: "", reason: "", status: "available" });

export function usePrettyIdsPage() {
    const abilities = useAppUserAbilities();
    const confirm = useConfirm();
    const { showToast } = useToast();
    const [poolPage, setPoolPage] = useState(1);
    const [poolStatus, setPoolStatus] = useState("");
    const [poolTrack, setPoolTrack] = useState("");
    const [idPage, setIdPage] = useState(1);
    const [idKeyword, setIdKeyword] = useState("");
    const [idStatus, setIdStatus] = useState("");
    const [idSource, setIdSource] = useState("");
    const [idPoolId, setIdPoolId] = useState("");
    const [assignedUserId, setAssignedUserId] = useState("");
    const [activeTab, setActiveTab] = useState("ids");
    const [activeDialog, setActiveDialog] = useState("");
    const [activePool, setActivePool] = useState(null);
    const [activePrettyID, setActivePrettyID] = useState(null);
    const [poolForm, setPoolForm] = useState(emptyPoolForm);
    const [generateForm, setGenerateForm] = useState(emptyGenerateForm);
    const [grantForm, setGrantForm] = useState(emptyGrantForm);
    const [statusForm, setStatusForm] = useState(emptyStatusForm);
    const [loadingAction, setLoadingAction] = useState("");

    // 靓号池和靓号明细是两个独立分页接口，筛选条件保持服务端字段名，避免在 hook 内再做一次字段映射。
    const poolFilters = useMemo(
        () => ({
            level_track: poolTrack,
            status: poolStatus,
        }),
        [poolStatus, poolTrack],
    );
    // 靓号明细筛选会直接透传到后台列表接口，assigned_user_id 在输入阶段已 trim，keyword 保留原值用于模糊搜索。
    const idFilters = useMemo(
        () => ({
            assigned_user_id: assignedUserId,
            keyword: idKeyword,
            pool_id: idPoolId,
            source: idSource,
            status: idStatus,
        }),
        [assignedUserId, idKeyword, idPoolId, idSource, idStatus],
    );

    const poolQuery = usePaginatedQuery({
        errorMessage: "加载靓号池失败",
        fetcher: listPrettyDisplayIDPools,
        filters: poolFilters,
        page: poolPage,
        pageSize,
        queryKey: ["pretty-id-pools", poolFilters, poolPage],
    });
    const idQuery = usePaginatedQuery({
        errorMessage: "加载靓号列表失败",
        fetcher: listPrettyDisplayIDs,
        filters: idFilters,
        page: idPage,
        pageSize,
        queryKey: ["pretty-ids", idFilters, idPage],
    });

    // 生成弹窗和明细筛选只需要当前已加载池列表；没有额外拉全量，避免页面初始化时放大后台查询。
    const poolOptions = useMemo(
        () =>
            (poolQuery.data.items || []).map((pool) => ({
                label: `${pool.name} · ${pool.minLevel}-${pool.maxLevel}`,
                value: pool.poolId,
            })),
        [poolQuery.data.items],
    );

    const openCreatePool = () => {
        setActivePool(null);
        setPoolForm(emptyPoolForm());
        setActiveDialog("pool");
    };

    const openEditPool = (pool) => {
        setActivePool(pool);
        // 编辑弹窗以服务端当前值为准回填，缺失字段只兜底到首版规则，避免把旧数据误清空。
        setPoolForm({
            levelTrack: pool.levelTrack || "wealth",
            maxLevel: pool.maxLevel ?? 10,
            minLevel: pool.minLevel ?? 1,
            name: pool.name || "",
            ruleConfigJson: pool.ruleConfigJson || "",
            ruleType: pool.ruleType || "aabbcc",
            sortOrder: pool.sortOrder || 0,
            status: pool.status || "active",
        });
        setActiveDialog("pool");
    };

    const openGenerate = (pool) => {
        setActivePool(pool || null);
        // 从池行进入时优先使用该池，从工具栏进入时沿用列表筛选池，减少管理员重复选择。
        setGenerateForm({
            ...emptyGenerateForm(),
            poolId: pool?.poolId || idPoolId || "",
            ruleConfigJson: pool?.ruleConfigJson || "",
            ruleType: pool?.ruleType || "aabbcc",
        });
        setActiveDialog("generate");
    };

    const openGrant = () => {
        setGrantForm(emptyGrantForm());
        setActiveDialog("grant");
    };

    const openStatus = (item) => {
        setActivePrettyID(item);
        // 状态弹窗默认给出最常用的反向操作：禁用中的号码恢复可用，其余未占用号码默认禁用。
        setStatusForm({
            prettyId: item?.prettyId || "",
            reason: "",
            status: item?.status === "disabled" ? "available" : "disabled",
        });
        setActiveDialog("status");
    };

    const closeDialog = () => {
        setActiveDialog("");
        setActivePool(null);
        setActivePrettyID(null);
    };

    const submitPool = async (event) => {
        event.preventDefault();
        await runAction("pool", activePool ? "靓号池已更新" : "靓号池已创建", async () => {
            // 表单字段使用前端 camelCase，提交边界统一转换为后端 JSON 的 snake_case。
            const form = parseForm(prettyDisplayIDPoolSchema, poolForm);
            const payload = {
                level_track: form.levelTrack,
                max_level: form.maxLevel,
                min_level: form.minLevel,
                name: form.name,
                rule_config_json: form.ruleConfigJson,
                rule_type: form.ruleType,
                sort_order: form.sortOrder,
                status: form.status,
            };
            if (activePool?.poolId) {
                await updatePrettyDisplayIDPool(activePool.poolId, payload);
            } else {
                await createPrettyDisplayIDPool(payload);
            }
            closeDialog();
            await reloadAll();
        });
    };

    const submitGenerate = async (event) => {
        event.preventDefault();
        await runAction("generate", "靓号已生成", async () => {
            // 批量生成只让后台接收池 ID、规则和数量，冲突过滤与批次审计由 user-service 事务完成。
            const form = parseForm(prettyDisplayIDGenerateSchema, generateForm);
            await generatePrettyDisplayIDs(form.poolId, {
                count: form.count,
                rule_config_json: form.ruleConfigJson,
                rule_type: form.ruleType,
            });
            closeDialog();
            await reloadAll();
        });
    };

    const submitGrant = async (event) => {
        event.preventDefault();
        await runAction("grant", "靓号已发放", async () => {
            const form = parseForm(prettyDisplayIDGrantSchema, grantForm);
            // 后台发放用 0 表示长期，正数天数在前端换算成毫秒，服务端只处理 duration_ms 这个统一单位。
            const days = Number(form.durationDays || 0);
            await grantPrettyDisplayID({
                display_user_id: form.displayUserId,
                duration_ms: days > 0 ? days * 24 * 60 * 60 * 1000 : 0,
                reason: form.reason,
                target_user_id: form.targetUserId,
            });
            closeDialog();
            await idQuery.reload();
        });
    };

    const submitStatus = async (event) => {
        event.preventDefault();
        await runAction("status", "靓号状态已更新", async () => {
            // 状态变更只允许未分配号码，前端提交 pretty_id 和目标状态，真正可变状态由后端再次校验。
            const form = parseForm(prettyDisplayIDStatusSchema, statusForm);
            await setPrettyDisplayIDStatus(form.prettyId, {
                reason: form.reason,
                status: form.status,
            });
            closeDialog();
            await idQuery.reload();
        });
    };

    const recyclePrettyID = async (item) => {
        if (!abilities.canPrettyUpdate || !canRecyclePrettyID(item)) {
            return;
        }
        const accepted = await confirm({
            title: "回收靓号",
            message: `确认回收靓号 ${item.displayUserId || item.prettyId}？回收后用户将恢复默认短号。`,
            confirmText: "回收",
            tone: "danger",
        });
        if (!accepted) {
            return;
        }
        await runAction(`recycle-${item.prettyId}`, "靓号已回收", async () => {
            // 回收只交给后台管理回收接口处理，前端不直接改 assigned/released 字段，避免和来源回收规则分叉。
            await recyclePrettyDisplayID(item.prettyId);
            await idQuery.reload();
        });
    };

    const changePoolStatus = (value) => {
        setPoolStatus(value);
        // 任意筛选变化都回到第一页，避免旧页码在新条件下落到空页。
        setPoolPage(1);
    };
    const changePoolTrack = (value) => {
        setPoolTrack(value);
        setPoolPage(1);
    };
    const changeIDKeyword = (value) => {
        setIdKeyword(value);
        // 明细列表的每个筛选项都会改变总数，页码统一回到第一页。
        setIdPage(1);
    };
    const changeIDStatus = (value) => {
        setIdStatus(value);
        setIdPage(1);
    };
    const changeIDSource = (value) => {
        setIdSource(value);
        setIdPage(1);
    };
    const changeIDPool = (value) => {
        setIdPoolId(value);
        setIdPage(1);
    };
    const changeAssignedUserId = (value) => {
        setAssignedUserId(value.trim());
        setIdPage(1);
    };

    const resetPoolFilters = () => {
        // 重置筛选后立即回到第一页，保持 URL 之外的页面状态和查询条件同步。
        setPoolStatus("");
        setPoolTrack("");
        setPoolPage(1);
    };
    const resetIDFilters = () => {
        // 靓号列表筛选项彼此独立，重置时一次性清空，避免残留 assigned_user_id 影响排查。
        setAssignedUserId("");
        setIdKeyword("");
        setIdPoolId("");
        setIdSource("");
        setIdStatus("");
        setIdPage(1);
    };

    const reloadAll = async () => {
        // 池配置会影响生成入口和号码列表展示，池相关操作完成后两个分页一起刷新。
        await Promise.all([poolQuery.reload(), idQuery.reload()]);
    };

    const runAction = async (action, successMessage, submitter) => {
        // 所有写操作共享 loading、toast 和异常展示；弹窗只在 submitter 内确认上游成功后关闭。
        setLoadingAction(action);
        try {
            await submitter();
            showToast(successMessage, "success");
        } catch (err) {
            showToast(err.message || "操作失败", "error");
        } finally {
            setLoadingAction("");
        }
    };

    return {
        abilities,
        activeDialog,
        activePool,
        activePrettyID,
        activeTab,
        assignedUserId,
        changeAssignedUserId,
        changeIDKeyword,
        changeIDPool,
        changeIDSource,
        changeIDStatus,
        changePoolStatus,
        changePoolTrack,
        closeDialog,
        generateForm,
        grantForm,
        idKeyword,
        idPage,
        idPoolId,
        idQuery,
        idSource,
        idStatus,
        loadingAction,
        openCreatePool,
        openEditPool,
        openGenerate,
        openGrant,
        openStatus,
        poolForm,
        poolOptions,
        poolPage,
        poolQuery,
        poolStatus,
        poolTrack,
        reloadAll,
        resetIDFilters,
        resetPoolFilters,
        recyclePrettyID,
        setActiveTab,
        setGenerateForm,
        setGrantForm,
        setIdPage,
        setPoolForm,
        setPoolPage,
        setStatusForm,
        statusForm,
        submitGenerate,
        submitGrant,
        submitPool,
        submitStatus,
    };
}

function canRecyclePrettyID(item) {
    const assigned = item?.assignedUserId;
    const hasAssignedUser =
        assigned !== 0 && assigned !== "0" && assigned !== "" && assigned !== undefined && assigned !== null;
    return Boolean(item?.prettyId) && item.status === "assigned" && hasAssignedUser;
}
