import { useCallback, useEffect, 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 { listResources } from "@/features/resources/api";
import {
    createAchievementDefinition,
    deleteAchievementDefinition,
    listAchievementDefinitions,
    updateAchievementDefinition,
} from "@/features/achievements/api";
import { useAchievementAbilities } from "@/features/achievements/permissions.js";
import { achievementFormSchema } from "@/features/achievements/schema";

const pageSize = 50;
const emptyData = { items: [], page: 1, pageSize, total: 0 };
const resourcePageQuery = { page: 1, page_size: 500, resource_type: "badge", status: "active" };
const emptyForm = (achievement = {}) => ({
    achievementType: achievement.achievementType || "ordinary",
    description: achievement.description || "",
    primaryBadgeResourceId: optionalId(achievement.primaryBadgeResourceId),
    sortOrder: String(achievement.sortOrder || 0),
    title: achievement.title || "",
});

export function useAchievementsPage() {
    const abilities = useAchievementAbilities();
    const confirm = useConfirm();
    const { showToast } = useToast();
    const [collectionType, setCollectionType] = useState("");
    const [collectionId, setCollectionId] = useState("");
    const [page, setPage] = useState(1);
    const [activeAction, setActiveAction] = useState("");
    const [selectedAchievement, setSelectedAchievement] = useState(null);
    const [form, setForm] = useState(() => emptyForm());
    const [loadingAction, setLoadingAction] = useState("");
    const [badgeResources, setBadgeResources] = useState([]);

    const filters = useMemo(
        () => ({
            collection_id: collectionId,
            collection_type: collectionType,
        }),
        [collectionId, collectionType],
    );
    const {
        data = emptyData,
        error,
        loading,
        reload,
    } = usePaginatedQuery({
        errorMessage: "加载成就配置失败",
        fetcher: listAchievementDefinitions,
        filters,
        page,
        pageSize,
        queryKey: ["achievements", filters, page],
    });

    const loadOptions = useCallback(async () => {
        try {
            const resourcePage = await listResources(resourcePageQuery);
            setBadgeResources(resourcePage.items || []);
        } catch (err) {
            showToast(err.message || "加载资源选项失败", "error");
        }
    }, [showToast]);

    useEffect(() => {
        void loadOptions();
    }, [loadOptions]);

    const changeCollectionType = resetSetter(setCollectionType, setPage);
    const changeCollectionId = resetSetter(setCollectionId, setPage);

    const resetFilters = () => {
        setCollectionType("");
        setCollectionId("");
        setPage(1);
    };

    const openCreate = () => {
        setSelectedAchievement(null);
        setForm(emptyForm());
        setActiveAction("create");
    };

    const openEdit = (achievement) => {
        if (!achievement?.achievementId) {
            return;
        }
        setSelectedAchievement(achievement);
        setForm(emptyForm(achievement));
        setActiveAction("edit");
    };

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

    const reloadAll = async () => {
        await Promise.all([reload(), loadOptions()]);
    };

    const submitAchievement = async (event) => {
        event.preventDefault();
        const editing = activeAction === "edit";
        if (editing && !selectedAchievement?.achievementId) {
            return;
        }
        await runAction(editing ? "edit" : "create", editing ? "成就已更新" : "成就已创建", async () => {
            const payload = buildAchievementPayload(parseForm(achievementFormSchema, form));
            if (editing) {
                await updateAchievementDefinition(selectedAchievement.achievementId, payload);
            } else {
                await createAchievementDefinition(payload);
            }
            closeAction();
            setForm(emptyForm());
            await reload();
        });
    };

    const deleteAchievement = async (achievement) => {
        if (!abilities.canUpdate || !achievement?.achievementId) {
            return;
        }
        const ok = await confirm({
            confirmText: "删除",
            message: `${achievement.title || achievement.achievementId} 会从成就配置列表和 App 成就列表移除，用户历史徽章展示保留。`,
            title: "删除成就",
            tone: "danger",
        });
        if (!ok) {
            return;
        }
        await runAction(`delete-${achievement.achievementId}`, "成就已删除", async () => {
            await deleteAchievementDefinition(achievement.achievementId);
            await reload();
        });
    };

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

    return {
        abilities,
        activeAction,
        badgeResources,
        changeCollectionId,
        changeCollectionType,
        closeAction,
        collectionId,
        collectionType,
        data,
        error,
        form,
        loading,
        loadingAction,
        openCreate,
        openEdit,
        page,
        reload: reloadAll,
        resetFilters,
        selectedAchievement,
        setForm,
        setPage,
        deleteAchievement,
        submitAchievement,
    };
}

function buildAchievementPayload(form) {
    const achievementType = form.achievementType;
    const collectionType = achievementType === "activity_limited" ? "event" : "ordinary";
    return {
        achievement_type: achievementType,
        auto_pin_policy: "none",
        collection_id: collectionType === "ordinary" ? "ordinary" : "",
        collection_type: collectionType,
        conditions: [],
        description: String(form.description || "").trim(),
        display_config_json: "{}",
        effective_from_ms: 0,
        effective_to_ms: 0,
        honor_visibility: true,
        primary_badge_resource_id: Number(form.primaryBadgeResourceId || 0),
        reward_resource_group_id: 0,
        sort_order: Number(form.sortOrder || 0),
        status: "active",
        title: String(form.title || "").trim(),
    };
}

function resetSetter(setter, setPage) {
    return (value) => {
        setter(value);
        setPage(1);
    };
}

function optionalId(value) {
    return value ? String(value) : "";
}
