import { useCallback, useEffect, useState } from "react";
import { parseForm } from "@/shared/forms/validation";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import { listResourceGroups } from "@/features/resources/api";
import { getRoomRocketConfig, updateRoomRocketConfig } from "@/features/room-rocket/api";
import { useRoomRocketAbilities } from "@/features/room-rocket/permissions.js";
import { roomRocketConfigFormSchema } from "@/features/room-rocket/schema";

const defaultThresholds = [1000, 3000, 6000, 10000, 15000];

export function useRoomRocketPage() {
    const abilities = useRoomRocketAbilities();
    const { showToast } = useToast();
    const [config, setConfig] = useState(null);
    const [configError, setConfigError] = useState("");
    const [configLoading, setConfigLoading] = useState(false);
    const [configSaving, setConfigSaving] = useState(false);
    const [form, setForm] = useState(emptyRoomRocketForm());
    const [resourceGroups, setResourceGroups] = useState([]);

    const reloadConfig = useCallback(async () => {
        setConfigLoading(true);
        setConfigError("");
        try {
            const [nextConfig, groups] = await Promise.all([
                getRoomRocketConfig(),
                listResourceGroups({ page: 1, page_size: 100, status: "active" }),
            ]);
            setConfig(nextConfig);
            setForm(formFromConfig(nextConfig));
            setResourceGroups(groups.items || []);
        } catch (err) {
            const message = err.message || "加载房间火箭配置失败";
            setConfigError(message);
            showToast(message, "error");
        } finally {
            setConfigLoading(false);
        }
    }, [showToast]);

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

    const resetForm = useCallback(() => {
        setForm(config ? formFromConfig(config) : emptyRoomRocketForm());
    }, [config]);

    const submitConfig = async (event, onSaved) => {
        event.preventDefault();
        if (!abilities.canUpdate) {
            return;
        }
        setConfigSaving(true);
        try {
            const parsed = parseForm(roomRocketConfigFormSchema, form);
            const saved = await updateRoomRocketConfig(payloadFromForm(parsed));
            setConfig(saved);
            setForm(formFromConfig(saved));
            showToast("房间火箭配置已保存", "success");
            onSaved?.(saved);
        } catch (err) {
            showToast(err.message || "保存房间火箭配置失败", "error");
        } finally {
            setConfigSaving(false);
        }
    };

    return {
        abilities,
        config,
        configError,
        configLoading,
        configSaving,
        form,
        reloadConfig,
        resetForm,
        resourceGroups,
        setForm,
        submitConfig,
    };
}

export function emptyRoomRocketForm() {
    return {
        broadcastDelayMs: "0",
        broadcastEnabled: true,
        broadcastScope: "region",
        enabled: false,
        fuelSource: "heat_value",
        giftFuelRules: [],
        levels: Array.from({ length: 5 }, (_, index) => ({
            animationUrl: "",
            coverUrl: "",
            fuelThreshold: String(defaultThresholds[index]),
            igniterRewards: [],
            inRoomRewards: [],
            level: index + 1,
            launchedImageUrl: "",
            launchAnimationUrl: "",
            top1Rewards: [],
        })),
        launchDelayMs: "30000",
        rewardStackPolicy: "allow_stack",
    };
}

function formFromConfig(config) {
    const fallback = emptyRoomRocketForm();
    return {
        broadcastDelayMs: String(config?.broadcastDelayMs ?? fallback.broadcastDelayMs),
        broadcastEnabled: Boolean(config?.broadcastEnabled),
        broadcastScope: config?.broadcastScope || fallback.broadcastScope,
        enabled: Boolean(config?.enabled),
        fuelSource: config?.fuelSource || fallback.fuelSource,
        giftFuelRules: (config?.giftFuelRules || []).map((rule, index) => ({
            excluded: Boolean(rule.excluded),
            fixedFuel: String(rule.fixedFuel || 0),
            giftId: rule.giftId || "",
            giftTypeCode: rule.giftTypeCode || "",
            multiplierPpm: String(rule.multiplierPpm || 0),
            ruleId: rule.ruleId || `gift_fuel_rule_${index + 1}`,
        })),
        levels: fallback.levels.map((fallbackLevel) => {
            const level = config?.levels?.find((item) => Number(item.level) === fallbackLevel.level) || fallbackLevel;
            return {
                animationUrl: level.animationUrl || "",
                coverUrl: level.coverUrl || "",
                fuelThreshold: String(level.fuelThreshold || fallbackLevel.fuelThreshold),
                igniterRewards: rewardsToForm(level.igniterRewards),
                inRoomRewards: rewardsToForm(level.inRoomRewards),
                level: fallbackLevel.level,
                launchedImageUrl: level.launchedImageUrl || "",
                launchAnimationUrl: level.launchAnimationUrl || "",
                top1Rewards: rewardsToForm(level.top1Rewards),
            };
        }),
        launchDelayMs: String(config?.launchDelayMs ?? fallback.launchDelayMs),
        rewardStackPolicy: config?.rewardStackPolicy || fallback.rewardStackPolicy,
    };
}

function rewardsToForm(rewards = []) {
    return rewards.map((reward, index) => ({
        displayName: reward.displayName || "",
        iconUrl: reward.iconUrl || "",
        quantity: String(reward.quantity || 1),
        resourceGroupId: reward.resourceGroupId ? String(reward.resourceGroupId) : "",
        rewardItemId: reward.rewardItemId || `reward_${index + 1}`,
        weight: String(reward.weight || 100),
    }));
}

function payloadFromForm(form) {
    return {
        broadcastDelayMs: Number(form.broadcastDelayMs || 0),
        broadcastEnabled: Boolean(form.broadcastEnabled),
        broadcastScope: form.broadcastScope,
        enabled: Boolean(form.enabled),
        fuelSource: form.fuelSource,
        giftFuelRules: form.giftFuelRules.map((rule, index) => ({
            excluded: Boolean(rule.excluded),
            fixedFuel: Number(rule.fixedFuel || 0),
            giftId: String(rule.giftId || "").trim(),
            giftTypeCode: String(rule.giftTypeCode || "").trim(),
            multiplierPpm: Number(rule.multiplierPpm || 0),
            ruleId: String(rule.ruleId || "").trim() || `gift_fuel_rule_${index + 1}`,
        })),
        levels: form.levels
            .map((level) => ({
                animationUrl: String(level.animationUrl || "").trim(),
                coverUrl: String(level.coverUrl || "").trim(),
                fuelThreshold: Number(level.fuelThreshold || 0),
                igniterRewards: rewardsFromForm(level.igniterRewards, level.level, "igniter"),
                inRoomRewards: rewardsFromForm(level.inRoomRewards, level.level, "in_room"),
                level: Number(level.level),
                launchedImageUrl: String(level.launchedImageUrl || "").trim(),
                launchAnimationUrl: String(level.launchAnimationUrl || "").trim(),
                top1Rewards: rewardsFromForm(level.top1Rewards, level.level, "top1"),
            }))
            .sort((left, right) => left.level - right.level),
        launchDelayMs: Number(form.launchDelayMs || 0),
        rewardStackPolicy: form.rewardStackPolicy,
    };
}

function rewardsFromForm(rewards = [], level, role) {
    return rewards
        .map((reward, index) => ({
            displayName: String(reward.displayName || "").trim(),
            iconUrl: String(reward.iconUrl || "").trim(),
            quantity: Number(reward.quantity || 1),
            resourceGroupId: Number(reward.resourceGroupId || 0),
            rewardItemId: String(reward.rewardItemId || "").trim() || `level_${level}_${role}_${index + 1}`,
            weight: Number(reward.weight || 0),
        }))
        .filter(
            (reward) =>
                reward.resourceGroupId || reward.weight || reward.quantity || reward.displayName || reward.iconUrl,
        );
}
