import { resourceMetadataJSON } from "@/features/resources/resourceMetadata.js";

export const resourceBatchUploadSize = 10;

const resourceCodeMaxLength = 96;
const resourceCodeSuffixLength = 3;
const randomResourceCodeChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const resourceTypeAliases = new Map([
    ["头像框", "avatar_frame"],
    ["坐骑", "vehicle"],
    ["座驾", "vehicle"],
    ["气泡", "chat_bubble"],
    ["勋章", "badge"],
    ["徽章", "badge"],
    ["飘窗", "floating_screen"],
    ["飘屏", "floating_screen"],
    ["mic声波", "mic_seat_animation"],
    ["麦位动效", "mic_seat_animation"],
    ["背景卡", "profile_card"],
    ["资料卡", "profile_card"],
    ["礼物", "gift"],
]);

const pricedResourceTypes = new Set(["avatar_frame", "vehicle", "gift"]);
const translationTimeoutMs = 2500;
const localNameTranslations = new Map([
    ["星光", "starlight"],
    ["星辰", "stars"],
    ["守护", "guardian"],
    ["夜色", "nightfall"],
    ["律动", "rhythm"],
    ["清新", "fresh"],
    ["梦幻", "dream"],
    ["浪漫", "romance"],
    ["彩虹", "rainbow"],
    ["月光", "moonlight"],
    ["阳光", "sunshine"],
    ["火焰", "flame"],
    ["冰雪", "snow"],
    ["海洋", "ocean"],
    ["森林", "forest"],
    ["皇冠", "crown"],
    ["皇家", "royal"],
    ["黄金", "gold"],
    ["白银", "silver"],
    ["青铜", "bronze"],
    ["钻石", "diamond"],
    ["爱心", "heart"],
    ["玫瑰", "rose"],
    ["天使", "angel"],
    ["恶魔", "devil"],
    ["贵族", "noble"],
    ["幸运", "lucky"],
    ["超级", "super"],
    ["炫彩", "colorful"],
    ["流光", "glow"],
    ["闪耀", "sparkle"],
    ["典藏", "classic"],
    ["限定", "limited"],
]);

export function parseResourceFolderFiles(fileList) {
    const files = Array.from(fileList || []).filter((file) => file?.name && !file.name.startsWith("."));
    const groups = new Map();

    files.forEach((file) => {
        const parsed = parseResourceFilename(file);
        if (!parsed.ok) {
            return;
        }

        const key = [parsed.resourceType, parsed.name, parsed.price, parsed.badgeForm].join("|");
        const current = groups.get(key) || {
            badgeForm: parsed.badgeForm,
            coverFile: null,
            animationFile: null,
            name: parsed.name,
            price: parsed.price,
            resourceType: parsed.resourceType,
        };

        const fileKey = parsed.role === "cover" ? "coverFile" : "animationFile";
        if (!current[fileKey]) {
            current[fileKey] = file;
        }
        groups.set(key, current);
    });

    const resources = Array.from(groups.values())
        .filter((item) => item.coverFile && item.animationFile)
        .map((item, index) => ({
            ...item,
            resourceCode: initialResourceCodeFor(item, index),
        }));

    return {
        errors: [],
        resources,
    };
}

export function resourcePlanToPayload(item) {
    const coinPrice = pricedResourceTypes.has(item.resourceType) ? Number(item.price || 0) : 0;
    return {
        amount: 0,
        animationUrl: item.animationUrl,
        assetUrl: item.animationUrl,
        badgeForm: item.resourceType === "badge" ? item.badgeForm || "tile" : undefined,
        badgeKind: item.resourceType === "badge" ? "normal" : undefined,
        coinPrice,
        managerGrantEnabled: true,
        metadataJson: resourceMetadataJSON(item.resourceType, item.metadataJson),
        name: item.name,
        previewUrl: item.coverUrl,
        priceType: coinPrice > 0 ? "coin" : "free",
        resourceCode: item.resourceCode,
        resourceType: item.resourceType,
        sortOrder: 0,
        status: "active",
    };
}

export async function translateResourceCodes(resources, options = {}) {
    const translated = [];
    for (let index = 0; index < resources.length; index += 1) {
        const resourceCode = await resourceCodeFor(resources[index], index);
        translated.push({
            ...resources[index],
            resourceCode: appendRandomResourceCodeSuffix(resourceCode, index),
        });
        options.onProgress?.({
            completed: index + 1,
            index,
            resource: translated[index],
            total: resources.length,
        });
    }
    return translated;
}

function parseResourceFilename(file) {
    const baseName = stripExtension(file.name);
    const parts = baseName
        .split("_")
        .map((part) => part.trim())
        .filter(Boolean);
    if (parts.length < 3) {
        return { ok: false };
    }

    const role = normalizeRole(parts[parts.length - 1]);
    if (!role) {
        return { ok: false };
    }

    const resourceType = resourceTypeAliases.get(parts[0].toLowerCase()) || resourceTypeAliases.get(parts[0]);
    if (!resourceType) {
        return { ok: false };
    }

    const name = parts[1];
    if (!name) {
        return { ok: false };
    }

    let price = 0;
    let badgeForm = "tile";
    if (pricedResourceTypes.has(resourceType)) {
        price = Number(parts[2]);
        if (!Number.isInteger(price) || price <= 0) {
            return { ok: false };
        }
    } else if (resourceType === "badge") {
        const formToken = parts.length >= 4 ? parts[2] : "";
        badgeForm = formToken === "长" || formToken === "long" || formToken === "strip" ? "strip" : "tile";
    }

    return { ok: true, badgeForm, name, price, resourceType, role };
}

function normalizeRole(value) {
    const role = String(value || "")
        .trim()
        .toLowerCase();
    if (role === "cover" || role === "封面") {
        return "cover";
    }
    if (role === "animation" || role === "anim" || role === "动效") {
        return "animation";
    }
    return "";
}

async function resourceCodeFor(item, index) {
    const name = String(item.name || "").trim();
    if (!name) {
        return fallbackResourceCode(index);
    }
    if (!hasChinese(name)) {
        return slugifyResourceCode(name) || fallbackResourceCode(index);
    }

    const translated = await translateChineseToEnglish(name);
    return slugifyResourceCode(translated) || fallbackResourceCode(index);
}

function initialResourceCodeFor(item, index) {
    return String(item.name || "").trim() || fallbackResourceCode(index);
}

async function translateChineseToEnglish(text) {
    const translators = [
        translateWithMyMemory,
        (value) => translateWithLingva(value, "https://lingva.ml"),
        (value) => translateWithLingva(value, "https://lingva.lunar.icu"),
        (value) => translateWithLibreTranslate(value, "https://translate.argosopentech.com"),
        translateWithLocalDictionary,
    ];

    for (const translator of translators) {
        try {
            const translated = String((await translator(text)) || "").trim();
            if (translated && !hasChinese(translated)) {
                return translated;
            }
        } catch {
            // Public translation endpoints are best-effort; continue to the next provider.
        }
    }
    return "";
}

async function translateWithMyMemory(text) {
    const url = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(text)}&langpair=zh-CN|en`;
    const data = await fetchJSON(url);
    return data?.responseData?.translatedText || "";
}

async function translateWithLingva(text, host) {
    const url = `${host}/api/v1/zh/en/${encodeURIComponent(text)}`;
    const data = await fetchJSON(url);
    return data?.translation || "";
}

async function translateWithLibreTranslate(text, host) {
    const body = new URLSearchParams({
        format: "text",
        q: text,
        source: "zh",
        target: "en",
    });
    const data = await fetchJSON(`${host}/translate`, {
        body,
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        method: "POST",
    });
    return data?.translatedText || "";
}

function translateWithLocalDictionary(text) {
    let index = 0;
    const parts = [];
    const keys = Array.from(localNameTranslations.keys()).sort((left, right) => right.length - left.length);
    while (index < text.length) {
        const rest = text.slice(index);
        const matched = keys.find((key) => rest.startsWith(key));
        if (matched) {
            parts.push(localNameTranslations.get(matched));
            index += matched.length;
            continue;
        }

        const char = text[index];
        if (/[a-z0-9]/i.test(char)) {
            parts.push(char);
            index += 1;
            continue;
        }
        if (hasChinese(char)) {
            return "";
        }
        index += 1;
    }
    return parts.join(" ");
}

async function fetchJSON(url, options = {}) {
    const controller = new AbortController();
    const timeout = window.setTimeout(() => controller.abort(), translationTimeoutMs);
    try {
        const response = await fetch(url, { ...options, signal: controller.signal });
        if (!response.ok) {
            return null;
        }
        return response.json();
    } finally {
        window.clearTimeout(timeout);
    }
}

function slugifyResourceCode(value) {
    return String(value || "")
        .normalize("NFKD")
        .replace(/[\u0300-\u036f]/g, "")
        .replace(/['’]/g, "")
        .replace(/&/g, " and ")
        .replace(/[^a-z0-9]+/gi, "_")
        .replace(/^_+|_+$/g, "")
        .toLowerCase()
        .slice(0, resourceCodeMaxLength);
}

function fallbackResourceCode(index) {
    return `resource_${String(index + 1).padStart(2, "0")}`;
}

function appendRandomResourceCodeSuffix(value, index) {
    const suffix = `_${randomResourceCodeChar()}${randomResourceCodeChar()}`;
    const maxBaseLength = resourceCodeMaxLength - resourceCodeSuffixLength;
    const base = String(value || fallbackResourceCode(index))
        .slice(0, maxBaseLength)
        .replace(/_+$/g, "");
    return `${base || fallbackResourceCode(index)}${suffix}`;
}

function randomResourceCodeChar() {
    return randomResourceCodeChars[Math.floor(Math.random() * randomResourceCodeChars.length)];
}

function hasChinese(value) {
    return /[\u3400-\u9fff]/.test(String(value || ""));
}

function stripExtension(filename) {
    return String(filename || "").replace(/\.[^.]+$/, "");
}
