import { useCallback, useEffect, useMemo, useState } from "react";
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import { emptyUserIdentityFilter, userIdentityFilterParams } from "@/shared/ui/userIdentityFilter.js";
import { listResourceGroups } from "@/features/resources/api";
import {
    getRegistrationRewardConfig,
    listRegistrationRewardClaims,
    updateRegistrationRewardConfig,
} from "@/features/registration-reward/api";
import { useRegistrationRewardAbilities } from "@/features/registration-reward/permissions.js";

const pageSize = 50;
const emptyClaims = { items: [], page: 1, pageSize, todayClaimedCount: 0, total: 0 };
const emptyTimeRange = { endMs: "", startMs: "" };

const emptyForm = {
    coinAmount: "",
    dailyLimit: "0",
    enabled: false,
    resourceGroupId: "",
    rewardType: "coin",
};

export function useRegistrationRewardPage() {
    const abilities = useRegistrationRewardAbilities();
    const { showToast } = useToast();
    const [config, setConfig] = useState(null);
    const [configDrawerOpen, setConfigDrawerOpen] = useState(false);
    const [form, setForm] = useState(emptyForm);
    const [configLoading, setConfigLoading] = useState(false);
    const [configSaving, setConfigSaving] = useState(false);
    const [resourceGroups, setResourceGroups] = useState([]);
    const [userFilter, setUserFilter] = useState(emptyUserIdentityFilter);
    const [status, setStatus] = useState("");
    const [timeRange, setTimeRange] = useState(emptyTimeRange);
    const [page, setPage] = useState(1);
    const filters = useMemo(
        () => ({
            claimed_end_ms: timeRange.endMs || undefined,
            claimed_start_ms: timeRange.startMs || undefined,
            status,
            ...userIdentityFilterParams(userFilter),
        }),
        [status, timeRange, userFilter],
    );
    const {
        data: claims = emptyClaims,
        error: claimsError,
        loading: claimsLoading,
        reload: reloadClaims,
    } = usePaginatedQuery({
        errorMessage: "加载领取记录失败",
        fetcher: listRegistrationRewardClaims,
        filters,
        page,
        pageSize,
        queryKey: ["registration-reward-claims", filters, page],
    });

    const reloadConfig = useCallback(async () => {
        setConfigLoading(true);
        try {
            const [config, groups] = await Promise.all([
                getRegistrationRewardConfig(),
                listResourceGroups({ page: 1, page_size: 100, status: "active" }),
            ]);
            setConfig(config);
            setForm(formFromConfig(config));
            setResourceGroups(groups.items || []);
        } catch (err) {
            showToast(err.message || "加载注册奖励配置失败", "error");
        } finally {
            setConfigLoading(false);
        }
    }, [showToast]);

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

    const openConfigDrawer = useCallback(() => {
        if (config) {
            setForm(formFromConfig(config));
        }
        setConfigDrawerOpen(true);
    }, [config]);

    const closeConfigDrawer = useCallback(() => {
        setConfigDrawerOpen(false);
        if (config) {
            setForm(formFromConfig(config));
            return;
        }
        setForm(emptyForm);
    }, [config]);

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

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

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

    const resetFilters = () => {
        setUserFilter(emptyUserIdentityFilter);
        setStatus("");
        setTimeRange(emptyTimeRange);
        setPage(1);
    };

    const submitConfig = async (event) => {
        event.preventDefault();
        if (!abilities.canUpdate) {
            return;
        }
        setConfigSaving(true);
        try {
            const saved = await updateRegistrationRewardConfig(payloadFromForm(form));
            setConfig(saved);
            setForm(formFromConfig(saved));
            setConfigDrawerOpen(false);
            showToast("注册奖励配置已保存", "success");
            await reloadClaims();
        } catch (err) {
            showToast(err.message || "保存注册奖励配置失败", "error");
        } finally {
            setConfigSaving(false);
        }
    };

    return {
        abilities,
        changeStatus,
        changeTimeRange,
        changeUserFilter,
        claims,
        claimsError,
        claimsLoading,
        closeConfigDrawer,
        config,
        configDrawerOpen,
        configLoading,
        configSaving,
        form,
        openConfigDrawer,
        page,
        reloadClaims,
        reloadConfig,
        resetFilters,
        resourceGroups,
        setForm,
        setPage,
        status,
        submitConfig,
        timeRange,
        userFilter,
    };
}

function formFromConfig(config) {
    return {
        coinAmount: config.coinAmount ? String(config.coinAmount) : "",
        dailyLimit: String(config.dailyLimit || 0),
        enabled: Boolean(config.enabled),
        resourceGroupId: config.resourceGroupId ? String(config.resourceGroupId) : "",
        rewardType: config.rewardType || "coin",
    };
}

function payloadFromForm(form) {
    const rewardType = form.rewardType === "resource_group" ? "resource_group" : "coin";
    const coinAmount = Number(form.coinAmount || 0);
    const resourceGroupId = Number(form.resourceGroupId || 0);
    const dailyLimit = Number(form.dailyLimit || 0);
    if (dailyLimit < 0) {
        throw new Error("每日限制不能小于 0");
    }
    if (rewardType === "coin" && coinAmount <= 0) {
        throw new Error("金币奖励必须大于 0");
    }
    if (rewardType === "resource_group" && resourceGroupId <= 0) {
        throw new Error("请选择资源组");
    }
    return {
        coin_amount: rewardType === "coin" ? coinAmount : 0,
        daily_limit: dailyLimit,
        enabled: Boolean(form.enabled),
        resource_group_id: rewardType === "resource_group" ? resourceGroupId : 0,
        reward_type: rewardType,
    };
}
