const HARD_MAX_VARIANTS = 8;
const AMBIGUOUS_MULTI_VARIANTS = 3;
const KOREAN_COUNT_WORDS = [
    [/(?:한|하나|1)\s*(?:장|개|가지|컷|시안|버전)/u, 1],
    [/(?:두|둘|2)\s*(?:장|개|가지|컷|시안|버전)/u, 2],
    [/(?:세|셋|3)\s*(?:장|개|가지|컷|시안|버전)/u, 3],
    [/(?:네|넷|4)\s*(?:장|개|가지|컷|시안|버전)/u, 4],
    [/(?:다섯|5)\s*(?:장|개|가지|컷|시안|버전)/u, 5],
    [/(?:여섯|6)\s*(?:장|개|가지|컷|시안|버전)/u, 6],
    [/(?:일곱|7)\s*(?:장|개|가지|컷|시안|버전)/u, 7],
    [/(?:여덟|8)\s*(?:장|개|가지|컷|시안|버전)/u, 8],
];
const ENGLISH_COUNT_WORDS = [
    [/\b(?:one|1)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 1],
    [/\b(?:two|2)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 2],
    [/\b(?:three|3)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 3],
    [/\b(?:four|4)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 4],
    [/\b(?:five|5)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 5],
    [/\b(?:six|6)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 6],
    [/\b(?:seven|7)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 7],
    [/\b(?:eight|8)\s*(?:image|variant|version|option|candidate|shot|render)?s?\b/iu, 8],
];
export function deriveAgentGenerationPlan({ prompt, settings, command = null }) {
    if (command?.name === "question" || command?.name === "help") {
        return {
            mode: "question",
            prompts: [],
            requestedVariants: 0,
            plannedVariants: 0,
            plannedParallelism: 0,
            source: "question-command",
            reason: command.name === "help" ? "Slash help answered without image generation." : "Question command answered without image generation.",
            command: command.name,
            assistantText: null,
        };
    }
    if (isVideoIntent(prompt)) {
        return {
            mode: "video",
            prompts: [prompt],
            requestedVariants: 1,
            plannedVariants: 1,
            plannedParallelism: 1,
            source: "auto-request",
            reason: "Video generation detected from prompt keywords.",
            command: command?.name ?? null,
            assistantText: null,
        };
    }
    const variantDecision = decideVariantCount(prompt, settings, command);
    const plannedParallelism = resolvePlannedParallelism(settings, variantDecision.count, command);
    const prompts = buildGenerationPrompts(prompt, variantDecision.count);
    return {
        mode: prompts.length > 1 ? "fanout" : "single",
        prompts,
        requestedVariants: variantDecision.requested,
        plannedVariants: prompts.length,
        plannedParallelism,
        source: variantDecision.source,
        reason: variantDecision.reason,
        command: command?.name ?? null,
        assistantText: null,
    };
}
export function normalizeAgentGenerationPlan(prompt, value, settings) {
    const input = value && typeof value === "object" ? value : {};
    const prompts = cleanPromptArray(input.prompts);
    if (prompts.length === 0)
        return deriveAgentGenerationPlan({ prompt, settings, command: cleanCommand(input.command) });
    const plannedVariants = cleanCount(input.plannedVariants, prompts.length, 0, HARD_MAX_VARIANTS);
    const requestedParallelism = cleanCount(input.plannedParallelism, settings.parallelism, 1, HARD_MAX_VARIANTS);
    const plannedParallelism = resolvePlannedParallelism({ ...settings, parallelism: requestedParallelism }, plannedVariants, null);
    return {
        mode: input.mode === "question" ? "question" : input.mode === "video" ? "video" : prompts.length > 1 ? "fanout" : "single",
        prompts,
        requestedVariants: cleanCount(input.requestedVariants, plannedVariants, 0, HARD_MAX_VARIANTS),
        plannedVariants,
        plannedParallelism,
        source: cleanPlanSource(input.source),
        reason: cleanReason(input.reason, prompts.length > 1 ? "Stored fanout plan." : "Stored single-image plan."),
        command: cleanCommandName(input.command),
        assistantText: typeof input.assistantText === "string" ? input.assistantText : null,
    };
}
function decideVariantCount(prompt, settings, command) {
    if (command?.name === "variants" || command?.name === "generate") {
        const count = clampCount(command.value ?? AMBIGUOUS_MULTI_VARIANTS, HARD_MAX_VARIANTS);
        return {
            count,
            requested: count,
            source: "slash-command",
            reason: `Slash command requested ${count} variant${count === 1 ? "" : "s"}.`,
        };
    }
    if (settings.generationStrategy === "manual") {
        const count = clampCount(settings.variants, HARD_MAX_VARIANTS);
        return {
            count,
            requested: count,
            source: "manual-settings",
            reason: `Manual settings requested ${count} variant${count === 1 ? "" : "s"}.`,
        };
    }
    const inferred = inferRequestedVariantCount(prompt);
    const capped = Math.min(inferred.count, clampCount(settings.maxAutoVariants, HARD_MAX_VARIANTS));
    return {
        count: capped,
        requested: inferred.count,
        source: inferred.count > 1 ? "auto-request" : "auto-default",
        reason: capped < inferred.count
            ? `User request implied ${inferred.count} variants; capped at ${capped}.`
            : inferred.reason,
    };
}
function inferRequestedVariantCount(prompt) {
    const text = prompt.trim();
    for (const [pattern, count] of [...KOREAN_COUNT_WORDS, ...ENGLISH_COUNT_WORDS]) {
        if (pattern.test(text)) {
            return { count, reason: `User request explicitly implies ${count} variant${count === 1 ? "" : "s"}.` };
        }
    }
    if (/(?:여러|몇\s*가지|시안|후보|버전|다양하게|several|multiple|options|variants|versions|candidates|alternatives)/iu.test(text)) {
        return { count: AMBIGUOUS_MULTI_VARIANTS, reason: `User request asks for multiple options; planning ${AMBIGUOUS_MULTI_VARIANTS} variants.` };
    }
    if (/(?:비교|대안|a\/b|compare|comparison)/iu.test(text)) {
        return { count: 2, reason: "User request implies comparison; planning 2 variants." };
    }
    return { count: 1, reason: "Defaulting to one image because the request did not ask for multiple variants." };
}
function resolvePlannedParallelism(settings, plannedVariants, command) {
    if (plannedVariants <= 0)
        return 0;
    const requested = command?.name === "parallelism" && command.value ? command.value : settings.parallelism;
    const providerCap = settings.provider === "oauth" ? 2 : HARD_MAX_VARIANTS;
    const qualityCap = settings.quality === "high" ? 2 : HARD_MAX_VARIANTS;
    return Math.max(1, Math.min(plannedVariants, clampCount(requested, HARD_MAX_VARIANTS), providerCap, qualityCap));
}
function buildGenerationPrompts(prompt, count) {
    if (count <= 1)
        return [prompt];
    return Array.from({ length: count }, (_, index) => [
        prompt,
        "",
        `Variant ${index + 1}/${count}: explore a distinct composition while preserving the request.`,
    ].join("\n"));
}
function cleanPromptArray(value) {
    if (!Array.isArray(value))
        return [];
    return value.filter((item) => typeof item === "string" && item.trim().length > 0)
        .slice(0, HARD_MAX_VARIANTS)
        .map((item) => item.trim());
}
function cleanPlanSource(value) {
    if (value === "auto-default" ||
        value === "auto-request" ||
        value === "manual-settings" ||
        value === "slash-command" ||
        value === "question-command")
        return value;
    return "auto-default";
}
function cleanCommandName(value) {
    if (value === "question" ||
        value === "help" ||
        value === "variants" ||
        value === "generate" ||
        value === "parallelism")
        return value;
    return null;
}
function cleanCommand(value) {
    if (!value || typeof value !== "object")
        return null;
    const input = value;
    const name = cleanCommandName(input.name);
    if (!name)
        return null;
    return {
        name,
        rawName: typeof input.rawName === "string" ? input.rawName : name,
        raw: typeof input.raw === "string" ? input.raw : "",
        prompt: typeof input.prompt === "string" ? input.prompt : "",
        ...(typeof input.value === "number" ? { value: input.value } : {}),
    };
}
function cleanReason(value, fallback) {
    return typeof value === "string" && value.trim() ? value.trim().slice(0, 240) : fallback;
}
function cleanCount(value, fallback, min, max) {
    const numeric = typeof value === "number" ? value : Number(value);
    if (!Number.isFinite(numeric))
        return fallback;
    return Math.max(min, Math.min(max, Math.round(numeric)));
}
function clampCount(value, max) {
    return Math.max(1, Math.min(max, Math.round(value)));
}
const VIDEO_INTENT_PATTERN = /(?:^|\s|[^\p{L}])(?:video|animate|animation)(?:\s|[^\p{L}]|$)|(?:동영상|비디오|영상|애니메이트|움직이|클립)/iu;
function isVideoIntent(prompt) {
    return VIDEO_INTENT_PATTERN.test(prompt);
}
const DURATION_PATTERN = /(\d{1,2})\s*(?:s|sec|seconds?|초)/i;
const RESOLUTION_PATTERN = /(720p|480p)/i;
const ASPECT_PATTERN = /(16:9|9:16|4:3|3:4|3:2|2:3|1:1)/;
export function parseVideoParams(prompt) {
    const params = {};
    const durMatch = DURATION_PATTERN.exec(prompt);
    if (durMatch) {
        const d = parseInt(durMatch[1]);
        if (d >= 1 && d <= 15)
            params.duration = d;
    }
    const resMatch = RESOLUTION_PATTERN.exec(prompt);
    if (resMatch)
        params.resolution = resMatch[1].toLowerCase();
    const aspMatch = ASPECT_PATTERN.exec(prompt);
    if (aspMatch)
        params.aspectRatio = aspMatch[1];
    return params;
}
