import { useCallback, useEffect, useMemo, useState } from "react";
import {
    getCPWeeklyRankConfig,
    listCPWeeklyRankSettlements,
    updateCPWeeklyRankConfig,
} from "@/features/cp-weekly-rank/api";
import { useCPWeeklyRankAbilities } from "@/features/cp-weekly-rank/permissions.js";
import { listResourceGroups } from "@/features/resources/api";
import { useToast } from "@/shared/ui/ToastProvider.jsx";

export const cpWeeklyRankRanks = [1, 2, 3];

export function useCPWeeklyRankPage() {
    const abilities = useCPWeeklyRankAbilities();
    const { showToast } = useToast();
    const [config, setConfig] = useState(defaultConfig());
    const [form, setForm] = useState(configToForm(defaultConfig()));
    const [resourceGroups, setResourceGroups] = useState([]);
    const [settlementRange, setSettlementRange] = useState(currentUTCWeekRange());
    const [settlements, setSettlements] = useState({ items: [], total: 0 });
    const [loading, setLoading] = useState(false);
    const [settlementsLoading, setSettlementsLoading] = useState(false);
    const [settlementsError, setSettlementsError] = useState("");
    const [drawerOpen, setDrawerOpen] = useState(false);
    const [saving, setSaving] = useState(false);

    const configuredRewardCount = useMemo(
        () => completeRewards(config.rewards || []).filter((reward) => Number(reward.resourceGroupId) > 0).length,
        [config.rewards],
    );

    const reloadConfig = useCallback(async () => {
        setLoading(true);
        try {
            const [remoteConfig, groups] = await Promise.all([
                getCPWeeklyRankConfig(),
                listResourceGroups({ page: 1, page_size: 200, status: "active" }),
            ]);
            const completed = completeConfig(remoteConfig);
            setConfig(completed);
            setForm(configToForm(completed));
            setResourceGroups(groups.items || []);
        } catch (err) {
            showToast(err.message || "加载 CP 排行活动配置失败", "error");
        } finally {
            setLoading(false);
        }
    }, [showToast]);

    const reloadSettlements = useCallback(
        async (range = settlementRange) => {
            setSettlementsLoading(true);
            setSettlementsError("");
            try {
                const page = await listCPWeeklyRankSettlements({
                    period_start_ms: Number(range.startMs || 0),
                    period_end_ms: Number(range.endMs || 0),
                });
                setSettlements(page);
            } catch (err) {
                setSettlementsError(err.message || "加载 CP 排行活动发奖记录失败");
            } finally {
                setSettlementsLoading(false);
            }
        },
        [settlementRange],
    );

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

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

    const reload = useCallback(async () => {
        await Promise.allSettled([reloadConfig(), reloadSettlements(settlementRange)]);
    }, [reloadConfig, reloadSettlements, settlementRange]);

    const openDrawer = () => {
        setForm(configToForm(config));
        setDrawerOpen(true);
    };

    const closeDrawer = () => {
        if (saving) {
            return;
        }
        setForm(configToForm(config));
        setDrawerOpen(false);
    };

    const updateForm = (patch) => {
        setForm((current) => ({ ...current, ...patch }));
    };

    const updateReward = (rankNo, patch) => {
        setForm((current) => ({
            ...current,
            rewards: completeRewardForms(current.rewards || []).map((reward) =>
                Number(reward.rankNo) === Number(rankNo) ? { ...reward, ...patch } : reward,
            ),
        }));
    };

    const submit = async (event) => {
        event.preventDefault();
        if (!abilities.canUpdate) {
            return;
        }
        let payload;
        try {
            payload = payloadFromForm(form);
        } catch (err) {
            showToast(err.message || "CP 排行活动配置参数不正确", "error");
            return;
        }
        setSaving(true);
        try {
            const saved = await updateCPWeeklyRankConfig(payload);
            const completed = completeConfig(saved);
            setConfig(completed);
            setForm(configToForm(completed));
            setDrawerOpen(false);
            showToast("CP 排行活动配置已保存", "success");
        } catch (err) {
            showToast(err.message || "保存 CP 排行活动配置失败", "error");
        } finally {
            setSaving(false);
        }
    };

    return {
        abilities,
        closeDrawer,
        config,
        configuredRewardCount,
        drawerOpen,
        form,
        loading,
        openDrawer,
        reload,
        reloadSettlements,
        resourceGroups,
        saving,
        settlementRange,
        settlements,
        settlementsError,
        settlementsLoading,
        setSettlementRange,
        submit,
        updateForm,
        updateReward,
    };
}

function defaultConfig() {
    return {
        activityCode: "cp_weekly_rank",
        enabled: true,
        relationType: "cp",
        topCount: 3,
        rewards: cpWeeklyRankRanks.map((rankNo) => ({ rankNo, resourceGroupId: 0 })),
    };
}

function completeConfig(config) {
    const completed = { ...defaultConfig(), ...(config || {}) };
    completed.topCount = 3;
    completed.relationType = "cp";
    completed.rewards = completeRewards(completed.rewards || []);
    return completed;
}

function completeRewards(rewards) {
    const byRank = new Map((rewards || []).map((reward) => [Number(reward.rankNo), reward]));
    return cpWeeklyRankRanks.map((rankNo) => ({
        rankNo,
        resourceGroupId: Number(byRank.get(rankNo)?.resourceGroupId || 0),
    }));
}

function configToForm(config) {
    const completed = completeConfig(config);
    return {
        enabled: completed.enabled !== false,
        rewards: completeRewards(completed.rewards).map((reward) => ({
            rankNo: reward.rankNo,
            resourceGroupId: reward.resourceGroupId ? String(reward.resourceGroupId) : "",
        })),
    };
}

function completeRewardForms(rewards) {
    const byRank = new Map((rewards || []).map((reward) => [Number(reward.rankNo), reward]));
    return cpWeeklyRankRanks.map((rankNo) => ({
        rankNo,
        resourceGroupId: byRank.get(rankNo)?.resourceGroupId || "",
    }));
}

function payloadFromForm(form) {
    const rewards = completeRewardForms(form.rewards || []).map((reward) => ({
        rank_no: Number(reward.rankNo),
        resource_group_id: Number(reward.resourceGroupId || 0),
    }));
    if (form.enabled !== false) {
        const missing = rewards.find(
            (reward) => !Number.isInteger(reward.resource_group_id) || reward.resource_group_id <= 0,
        );
        if (missing) {
            throw new Error(`Top${missing.rank_no} 奖励资源组必须配置`);
        }
    }
    return {
        enabled: form.enabled !== false,
        top_count: 3,
        rewards,
    };
}

function currentUTCWeekRange(now = new Date()) {
    const utcDayStart = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
    const weekday = now.getUTCDay() || 7;
    const startMs = utcDayStart - (weekday - 1) * 86400000;
    return { endMs: startMs + 7 * 86400000, startMs };
}
