import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useAppScope } from "@/app/app-scope/AppScopeProvider.jsx";
import { getVipConfig, getVipProgram, updateVipConfig, updateVipProgram } from "@/features/vip-config/api";
import { p1BenefitCatalog, vipBenefitResourceTypes, vipProgramDefaults } from "@/features/vip-config/constants.js";
import { normalizeVipBenefitMetadata } from "@/features/vip-config/metadata.js";
import { useVipConfigAbilities } from "@/features/vip-config/permissions.js";
import { vipConfigFormSchema, vipProgramFormSchema } from "@/features/vip-config/schema.js";
import { listResourceGroups, listResources } from "@/features/resources/api";
import { parseForm } from "@/shared/forms/validation";
import { useToast } from "@/shared/ui/ToastProvider.jsx";

const dayMillis = 24 * 60 * 60 * 1000;

export function useVipConfigPage() {
    const abilities = useVipConfigAbilities();
    const { appCode } = useAppScope();
    const { showToast } = useToast();
    const initialProgram = defaultProgram(appCode);
    const [program, setProgram] = useState(initialProgram);
    const [config, setConfig] = useState({ levels: defaultLevels(initialProgram) });
    const [programForm, setProgramForm] = useState(programToForm(initialProgram));
    const [form, setForm] = useState({
        levels: defaultLevels(initialProgram).map((level) => levelToForm(level, initialProgram)),
    });
    const [resourceGroups, setResourceGroups] = useState([]);
    const [resources, setResources] = useState([]);
    const [resourcesLoading, setResourcesLoading] = useState(false);
    const [editorMode, setEditorMode] = useState("");
    const [error, setError] = useState(null);
    const [loading, setLoading] = useState(false);
    const [saving, setSaving] = useState(false);
    const reloadSequence = useRef(0);
    const resourceLoadSequence = useRef(0);
    const resourcesApp = useRef("");

    const activeCount = useMemo(
        () => (config.levels || []).filter((level) => level.status === "active").length,
        [config.levels],
    );

    const reload = useCallback(async () => {
        const sequence = ++reloadSequence.current;
        setLoading(true);
        setError(null);
        try {
            const [remoteProgram, remoteConfig, groups] = await Promise.all([
                getVipProgram(),
                getVipConfig(),
                listResourceGroups({ page: 1, page_size: 100, status: "active" }),
            ]);
            if (sequence !== reloadSequence.current) {
                return;
            }
            const nextProgram = normalizeProgram(remoteProgram, appCode);
            const levels = completeVipLevels(remoteConfig.levels || [], nextProgram);
            setProgram(nextProgram);
            setProgramForm(programToForm(nextProgram));
            setConfig({ ...remoteConfig, levels });
            setForm({ levels: levels.map((level) => levelToForm(level, nextProgram)) });
            setResourceGroups(groups.items || []);
        } catch (err) {
            if (sequence !== reloadSequence.current) {
                return;
            }
            setError(err);
            showToast(err.message || "加载 VIP 配置失败", "error");
        } finally {
            if (sequence === reloadSequence.current) {
                setLoading(false);
            }
        }
    }, [appCode, showToast]);

    const loadResources = useCallback(async () => {
        if (resourcesApp.current === appCode) {
            return;
        }
        const sequence = ++resourceLoadSequence.current;
        setResourcesLoading(true);
        try {
            const resourceItems = await listAllVipResources();
            if (sequence !== resourceLoadSequence.current) {
                return;
            }
            setResources(resourceItems.filter((resource) => resource.resourceType !== "vip_trial_card"));
            resourcesApp.current = appCode;
        } catch (err) {
            if (sequence === resourceLoadSequence.current) {
                // 资源目录只影响装扮权益绑定；读取失败不关闭等级编辑，运营可退出后重进并重试。
                setResources([]);
                showToast(err.message || "加载权益资源失败", "error");
            }
        } finally {
            if (sequence === resourceLoadSequence.current) {
                setResourcesLoading(false);
            }
        }
    }, [appCode, showToast]);

    useEffect(() => {
        // X-App-Code 是隔离边界；切换 App 时必须丢弃上一 App 的编辑态并重新读取完整配置，避免跨 App 误保存。
        const fallback = defaultProgram(appCode);
        setProgram(fallback);
        setProgramForm(programToForm(fallback));
        setConfig({ levels: defaultLevels(fallback) });
        setForm({ levels: defaultLevels(fallback).map((level) => levelToForm(level, fallback)) });
        setResources([]);
        setResourcesLoading(false);
        resourcesApp.current = "";
        resourceLoadSequence.current += 1;
        setEditorMode("");
        void reload();
    }, [appCode, reload]);

    const openProgramEditor = () => {
        setProgramForm(programToForm(program));
        setEditorMode("program");
    };

    const openLevelsEditor = () => {
        setForm({
            levels: completeVipLevels(config.levels || [], program).map((level) => levelToForm(level, program)),
        });
        setEditorMode("levels");
        // 总览不依赖几百页资源目录；仅进入权益编辑时异步加载，避免阻塞 VIP 表格首屏。
        void loadResources();
    };

    const closeEditor = () => {
        if (saving) {
            return;
        }
        setProgramForm(programToForm(program));
        setForm({
            levels: completeVipLevels(config.levels || [], program).map((level) => levelToForm(level, program)),
        });
        setEditorMode("");
    };

    const updateProgramField = (patch) => {
        setProgramForm((current) => {
            const next = { ...current, ...patch };
            if (patch.programType && patch.programType !== current.programType) {
                // 体系决定产品已确认的等级数量；不允许切换体系后遗留另一体系的 9/10 级配置。
                next.levelCount = String(vipProgramDefaults[patch.programType].levelCount);
            }
            return next;
        });
    };

    const updateLevel = (levelNumber, patch) => {
        setForm((current) => ({
            ...current,
            levels: (current.levels || []).map((item) => (item.level === levelNumber ? { ...item, ...patch } : item)),
        }));
    };

    const updateBenefit = (levelNumber, benefitCode, patch) => {
        setForm((current) => ({
            ...current,
            levels: (current.levels || []).map((level) =>
                level.level !== levelNumber
                    ? level
                    : {
                          ...level,
                          benefits: (level.benefits || []).map((benefit) =>
                              benefit.benefitCode === benefitCode
                                  ? {
                                        ...benefit,
                                        ...patch,
                                        // 目录占位项只有在运营实际修改后才转成显式等级配置，避免打开并保存就补齐整张表。
                                        catalogPlaceholder: false,
                                    }
                                  : benefit,
                          ),
                      },
            ),
        }));
    };

    const updateAllBenefits = (levelNumber, status) => {
        setForm((current) => ({
            ...current,
            levels: (current.levels || []).map((level) =>
                level.level !== levelNumber
                    ? level
                    : {
                          ...level,
                          // “全选”只改变当前等级已有权益行，不按目录补齐缺项，保持 target_only 的最终快照语义。
                          benefits: (level.benefits || []).map((benefit) => ({
                              ...benefit,
                              status,
                              // 全选开启属于明确配置；取消全选时仍不把从未配置过的目录占位项写入数据库。
                              catalogPlaceholder: status === "active" ? false : benefit.catalogPlaceholder,
                          })),
                      },
            ),
        }));
    };

    const submitProgram = async (event) => {
        event.preventDefault();
        if (!abilities.canUpdate) {
            return;
        }
        let payload;
        try {
            payload = programPayloadFromForm(programForm);
        } catch (err) {
            showToast(err.message || "VIP 体系参数不正确", "error");
            return;
        }
        setSaving(true);
        try {
            const saved = normalizeProgram(await updateVipProgram(payload), appCode);
            setProgram(saved);
            setProgramForm(programToForm(saved));
            setEditorMode("");
            showToast("VIP 体系已保存", "success");
            await reload();
        } catch (err) {
            showToast(err.message || "保存 VIP 体系失败", "error");
        } finally {
            setSaving(false);
        }
    };

    const submitLevels = async (event) => {
        event.preventDefault();
        if (!abilities.canUpdate) {
            return;
        }
        let payload;
        try {
            payload = vipConfigPayloadFromForm(form, program);
        } catch (err) {
            showToast(err.message || "VIP 等级参数不正确", "error");
            return;
        }
        setSaving(true);
        try {
            const saved = await updateVipConfig(payload);
            const levels = completeVipLevels(saved.levels || [], program);
            setConfig({ ...saved, levels });
            setForm({ levels: levels.map((level) => levelToForm(level, program)) });
            setEditorMode("");
            showToast("VIP 等级与权益已保存", "success");
        } catch (err) {
            showToast(err.message || "保存 VIP 等级失败", "error");
        } finally {
            setSaving(false);
        }
    };

    return {
        abilities,
        activeCount,
        appCode,
        closeEditor,
        config,
        editorMode,
        error,
        form,
        loading,
        openLevelsEditor,
        openProgramEditor,
        program,
        programForm,
        reload,
        resourceGroups,
        resources,
        resourcesLoading,
        saving,
        submitLevels,
        submitProgram,
        updateAllBenefits,
        updateBenefit,
        updateLevel,
        updateProgramField,
    };
}

async function listAllVipResources() {
    const items = [];
    const pageSize = 100;
    for (let page = 1; page <= 200; page += 1) {
        const result = await listResources({ page, page_size: pageSize, status: "active" });
        items.push(...(result.items || []));
        if (items.length >= Number(result.total || 0) || (result.items || []).length < pageSize) {
            return items;
        }
    }
    throw new Error("权益资源数量超过后台可加载上限");
}

function defaultProgram(appCode) {
    const programType = String(appCode || "").toLowerCase() === "fami" ? "tiered_privilege_v1" : "legacy_timed";
    const defaults = vipProgramDefaults[programType];
    return {
        appCode: String(appCode || "").toLowerCase(),
        programType,
        levelCount: defaults.levelCount,
        status: "active",
        configVersion: 0,
        sameLevelExpiryPolicy: defaults.sameLevelExpiryPolicy,
        upgradeExpiryPolicy: defaults.upgradeExpiryPolicy,
        downgradePurchasePolicy: defaults.downgradePurchasePolicy,
        benefitInheritancePolicy: defaults.benefitInheritancePolicy,
        grantMode: defaults.grantMode,
        trialCardEnabled: defaults.trialCardEnabled,
    };
}

function normalizeProgram(program, appCode) {
    const fallback = defaultProgram(appCode);
    const programType = program?.programType === "tiered_privilege_v1" ? "tiered_privilege_v1" : "legacy_timed";
    const defaults = vipProgramDefaults[programType];
    const levelCount = Number(program?.levelCount || defaults.levelCount);
    return {
        ...fallback,
        ...program,
        appCode: program?.appCode || fallback.appCode,
        programType,
        levelCount: Number.isInteger(levelCount) && levelCount > 0 ? levelCount : defaults.levelCount,
        status: program?.status === "disabled" ? "disabled" : "active",
        sameLevelExpiryPolicy: program?.sameLevelExpiryPolicy || defaults.sameLevelExpiryPolicy,
        upgradeExpiryPolicy: program?.upgradeExpiryPolicy || defaults.upgradeExpiryPolicy,
        downgradePurchasePolicy: program?.downgradePurchasePolicy || defaults.downgradePurchasePolicy,
        benefitInheritancePolicy: program?.benefitInheritancePolicy || defaults.benefitInheritancePolicy,
        grantMode: program?.grantMode || defaults.grantMode,
        trialCardEnabled:
            typeof program?.trialCardEnabled === "boolean" ? program.trialCardEnabled : defaults.trialCardEnabled,
    };
}

function programToForm(program) {
    return {
        enabled: program.status !== "disabled",
        levelCount: String(program.levelCount || vipProgramDefaults[program.programType].levelCount),
        programType: program.programType,
    };
}

function programPayloadFromForm(form) {
    const parsed = parseForm(vipProgramFormSchema, form);
    const defaults = vipProgramDefaults[parsed.programType];
    const levelCount = Number(parsed.levelCount || 0);
    if (!Number.isInteger(levelCount) || levelCount <= 0 || levelCount > 20) {
        throw new Error("VIP 等级数量必须为 1 至 20");
    }
    return {
        programType: parsed.programType,
        levelCount,
        sameLevelExpiryPolicy: defaults.sameLevelExpiryPolicy,
        upgradeExpiryPolicy: defaults.upgradeExpiryPolicy,
        downgradePurchasePolicy: defaults.downgradePurchasePolicy,
        benefitInheritancePolicy: defaults.benefitInheritancePolicy,
        grantMode: defaults.grantMode,
        trialCardEnabled: defaults.trialCardEnabled,
        status: parsed.enabled ? "active" : "disabled",
    };
}

function defaultLevels(program) {
    return Array.from({ length: program.levelCount }, (_, index) => defaultLevel(index + 1));
}

function defaultLevel(level) {
    return {
        level,
        name: `VIP${level}`,
        status: "disabled",
        priceCoin: 0,
        durationMs: 30 * dayMillis,
        rewardResourceGroupId: 0,
        requiredRechargeCoinAmount: 0,
        rechargeGateRequired: false,
        sortOrder: level * 10,
        // target_only 下新等级从空权益快照开始；后台不能依据历史 unlockLevel 猜测并开启权益。
        benefits: [],
    };
}

export function completeVipLevels(levels, program) {
    const byLevel = new Map((levels || []).map((level) => [Number(level.level), level]));
    return defaultLevels(program).map((fallback) => {
        const existing = byLevel.get(fallback.level);
        if (!existing) {
            return fallback;
        }
        const merged = { ...fallback, ...existing };
        merged.benefits =
            program.programType === "tiered_privilege_v1"
                ? explicitP1Benefits(existing.benefits || [])
                : existing.benefits || [];
        return merged;
    });
}

function explicitP1Benefits(benefits) {
    // 每级权益是最终快照：只保留该等级真实返回的行，缺项既不按 unlockLevel 补齐，也不从体系目录继承。
    return (benefits || []).map((benefit) =>
        benefit.benefitCode === "daily_coin_rebate" ? { ...benefit, trialEnabled: false } : benefit,
    );
}

export function levelToForm(level, program) {
    return {
        level: Number(level.level || 0),
        name: level.name || `VIP${level.level}`,
        status: level.status || "disabled",
        priceCoin: level.priceCoin ? String(level.priceCoin) : "",
        durationDays: level.durationMs ? String(Math.max(1, Math.round(Number(level.durationMs) / dayMillis))) : "30",
        rewardResourceGroupId: level.rewardResourceGroupId ? String(level.rewardResourceGroupId) : "",
        sortOrder: String(level.sortOrder || Number(level.level || 0) * 10),
        benefits: benefitFormsForLevel(level, program),
    };
}

function benefitFormsForLevel(level, program) {
    const explicitBenefits = level.benefits || [];
    if (program?.programType !== "tiered_privilege_v1") {
        return explicitBenefits.map((benefit, index) => benefitToForm(benefit, level.level, index, false));
    }
    const catalog = completeP1BenefitCatalog(program?.benefits || []);
    const explicitByCode = new Map(explicitBenefits.map((benefit) => [benefit.benefitCode, benefit]));
    const catalogCodes = new Set(catalog.map((benefit) => benefit.benefitCode));
    const rows = catalog.map((template, index) => {
        const explicit = explicitByCode.get(template.benefitCode);
        return benefitToForm(explicit || template, level.level, index, !explicit);
    });
    // 服务端可能先上线新权益而当前前端目录尚未更新；显式行必须保留，不能因目录版本差异在保存时被删除。
    explicitBenefits.forEach((benefit, index) => {
        if (!catalogCodes.has(benefit.benefitCode)) {
            rows.push(benefitToForm(benefit, level.level, catalog.length + index, false));
        }
    });
    return rows;
}

function completeP1BenefitCatalog(remoteCatalog) {
    const remoteByCode = new Map(remoteCatalog.map((benefit) => [benefit.benefitCode, benefit]));
    const builtInCodes = new Set(p1BenefitCatalog.map((benefit) => benefit.benefitCode));
    const catalog = p1BenefitCatalog.map((template) => ({
        ...template,
        // 服务端最高等级行含最新名称、类型与执行域；内置目录只负责保证被删除的已知权益仍可重新配置。
        ...(remoteByCode.get(template.benefitCode) || {}),
    }));
    remoteCatalog.forEach((benefit) => {
        if (!builtInCodes.has(benefit.benefitCode)) {
            catalog.push(benefit);
        }
    });
    return catalog;
}

function benefitToForm(benefit, level, index, catalogPlaceholder) {
    const benefitCode = benefit.benefitCode || "";
    const expectedResourceType = vipBenefitResourceTypes[benefitCode] || "";
    return {
        benefitCode,
        name: benefit.name || benefitCode,
        benefitType: Boolean(expectedResourceType) || benefit.benefitType === "decoration" ? "decoration" : "function",
        unlockLevel: Number(benefit.unlockLevel || level || 1),
        status: catalogPlaceholder ? "disabled" : benefit.status === "active" ? "active" : "disabled",
        trialEnabled: benefitCode === "daily_coin_rebate" ? false : Boolean(benefit.trialEnabled),
        resourceId: catalogPlaceholder ? "" : benefit.resourceId ? String(benefit.resourceId) : "",
        resourceType: catalogPlaceholder ? "" : benefit.resourceType || "",
        executionScope: ["wallet", "room", "user", "notice"].includes(benefit.executionScope)
            ? benefit.executionScope
            : "wallet",
        autoEquip: Boolean(benefit.autoEquip),
        sortOrder: String(benefit.sortOrder || (index + 1) * 10),
        // 高等级目录只提供字段模板；等级未配置的参数必须从空对象开始，不能复制高等级返现金额、文案或资源。
        metadataJson: catalogPlaceholder ? "{}" : benefit.metadataJson || "{}",
        catalogPlaceholder,
    };
}

export function vipConfigPayloadFromForm(form, program) {
    const parsed = parseForm(vipConfigFormSchema, form);
    if (parsed.levels.length !== program.levelCount) {
        throw new Error(`当前体系必须完整配置 VIP1 至 VIP${program.levelCount}`);
    }
    const levels = parsed.levels.map((level) => levelPayload(level, program));
    return { levels };
}

function levelPayload(level, program) {
    const priceCoin = Number(level.priceCoin || 0);
    const durationDays = Number(level.durationDays || 0);
    const rewardResourceGroupId = Number(level.rewardResourceGroupId || 0);
    const sortOrder = Number(level.sortOrder || level.level * 10);
    const status = level.status === "active" ? "active" : "disabled";
    if (!Number.isInteger(priceCoin) || priceCoin < 0) {
        throw new Error(`VIP${level.level} 购买金币数不正确`);
    }
    if (!Number.isInteger(durationDays) || durationDays <= 0) {
        throw new Error(`VIP${level.level} 有效天数必须大于 0`);
    }
    if (!Number.isInteger(sortOrder) || sortOrder < 0) {
        throw new Error(`VIP${level.level} 排序不能小于 0`);
    }
    if (status === "active" && priceCoin <= 0) {
        throw new Error(`VIP${level.level} 启用时购买金币数必须大于 0`);
    }
    if (!Number.isInteger(rewardResourceGroupId) || rewardResourceGroupId < 0) {
        throw new Error(`VIP${level.level} 奖励资源组不正确`);
    }
    // Fami 的等级礼包是可选表现资源；经典 Lalu VIP 仍沿用启用等级必须配置礼包的既有约束。
    if (status === "active" && program.programType !== "tiered_privilege_v1" && rewardResourceGroupId <= 0) {
        throw new Error(`VIP${level.level} 启用时必须选择奖励资源组`);
    }
    const benefits = (level.benefits || [])
        // 未触碰的目录占位项只服务复选 UI；显式禁用行和运营修改后的占位项仍需提交，保持最终快照可审计。
        .filter((benefit) => !benefit.catalogPlaceholder || benefit.status === "active")
        .map((benefit) => benefitPayload(benefit, level.level));
    if (program.programType === "tiered_privilege_v1") {
        const benefitCodes = new Set(benefits.map((benefit) => benefit.benefitCode));
        if (benefitCodes.size !== benefits.length) {
            throw new Error(`VIP${level.level} 权益编码不能重复`);
        }
    }
    return {
        level: Number(level.level),
        name: String(level.name || "").trim(),
        status,
        priceCoin,
        durationMs: durationDays * dayMillis,
        rewardResourceGroupId,
        requiredRechargeCoinAmount: 0,
        sortOrder,
        benefits,
    };
}

function benefitPayload(benefit, level) {
    const rawMetadataJson = String(benefit.metadataJson || "{}").trim() || "{}";
    const sortOrder = Number(benefit.sortOrder || 0);
    const resourceId = Number(benefit.resourceId || 0);
    const expectedResourceType = vipBenefitResourceTypes[benefit.benefitCode] || "";
    if (!Number.isInteger(sortOrder) || sortOrder < 0) {
        throw new Error(`VIP${level} 的 ${benefit.name || benefit.benefitCode} 排序不能小于 0`);
    }
    try {
        const parsedConfig = JSON.parse(rawMetadataJson);
        if (!parsedConfig || Array.isArray(parsedConfig) || typeof parsedConfig !== "object") {
            throw new Error("config must be an object");
        }
    } catch {
        throw new Error(`VIP${level} 的 ${benefit.name || benefit.benefitCode} 元数据必须是 JSON 对象`);
    }
    if (!Number.isInteger(resourceId) || resourceId < 0) {
        throw new Error(`VIP${level} 的 ${benefit.name || benefit.benefitCode} 资源不正确`);
    }
    const status = benefit.status === "active" ? "active" : "disabled";
    if (expectedResourceType && status === "active" && resourceId <= 0) {
        throw new Error(`VIP${level} 的 ${benefit.name || benefit.benefitCode} 必须绑定真实资源`);
    }
    if (expectedResourceType && resourceId > 0 && benefit.resourceType !== expectedResourceType) {
        throw new Error(
            `VIP${level} 的 ${benefit.name || benefit.benefitCode} 只能绑定 ${expectedResourceType} 类型资源`,
        );
    }
    const metadataJson = normalizeVipBenefitMetadata({
        benefitCode: benefit.benefitCode,
        label: `VIP${level} 的 ${benefit.name || benefit.benefitCode}`,
        metadataJson: rawMetadataJson,
        status,
    });
    return {
        benefitCode: String(benefit.benefitCode || "").trim(),
        name: String(benefit.name || "").trim(),
        benefitType: Boolean(expectedResourceType) || benefit.benefitType === "decoration" ? "decoration" : "function",
        unlockLevel: Number(benefit.unlockLevel || level),
        status,
        trialEnabled: benefit.benefitCode === "daily_coin_rebate" ? false : Boolean(benefit.trialEnabled),
        resourceId,
        resourceType: resourceId > 0 ? String(benefit.resourceType || "").trim() : "",
        executionScope: benefit.executionScope,
        autoEquip: Boolean(benefit.autoEquip),
        sortOrder,
        metadataJson,
    };
}
