import { isNativeDisabledByEnv, makeNativeRequiredError } from './native-router-hotpath-policy.js';
import { loadNativeRouterHotpathBindingForInternalUse } from './native-router-hotpath.js';
function parsePositiveInt(value) {
    const parsed = Number(value);
    if (!Number.isFinite(parsed)) {
        return undefined;
    }
    const floored = Math.floor(parsed);
    return floored > 0 ? floored : undefined;
}
function parseRecurrence(value) {
    if (!value || typeof value !== 'object' || Array.isArray(value)) {
        return undefined;
    }
    const row = value;
    const kind = typeof row.kind === 'string' ? row.kind.trim().toLowerCase() : '';
    if (kind !== 'daily' && kind !== 'weekly' && kind !== 'interval') {
        return undefined;
    }
    const maxRuns = parsePositiveInt(row.maxRuns);
    if (!maxRuns) {
        return undefined;
    }
    if (kind === 'interval') {
        const everyMinutes = parsePositiveInt(row.everyMinutes);
        if (!everyMinutes) {
            return undefined;
        }
        return { kind, maxRuns, everyMinutes };
    }
    return { kind, maxRuns };
}
function parseCandidateRow(value) {
    if (!value || typeof value !== 'object' || Array.isArray(value)) {
        return null;
    }
    const row = value;
    const dueAt = typeof row.dueAt === 'string' ? row.dueAt.trim() : '';
    const task = typeof row.task === 'string' ? row.task.trim() : '';
    if (!dueAt || !task) {
        return null;
    }
    const recurrence = parseRecurrence(row.recurrence);
    if (row.recurrence !== undefined && !recurrence) {
        return null;
    }
    return recurrence ? { dueAt, task, recurrence } : { dueAt, task };
}
function parseNativeCandidatePayload(raw) {
    try {
        return parseCandidateRow(JSON.parse(raw));
    }
    catch {
        return null;
    }
}
function parseNativeTextPart(value) {
    if (!value || typeof value !== 'object' || Array.isArray(value)) {
        return null;
    }
    const row = value;
    const kind = typeof row.kind === 'string' ? row.kind.trim().toLowerCase() : '';
    if (kind === 'text') {
        const text = typeof row.text === 'string' ? row.text : '';
        return { kind: 'text', text };
    }
    if (kind !== 'directive') {
        return null;
    }
    const full = typeof row.full === 'string' ? row.full : '';
    if (!full) {
        return null;
    }
    const candidateRaw = row.candidate;
    if (candidateRaw === undefined || candidateRaw === null) {
        return { kind: 'directive', full };
    }
    const candidate = parseCandidateRow(candidateRaw);
    if (!candidate) {
        return null;
    }
    return { kind: 'directive', full, candidate };
}
function parseNativeTextPartsPayload(raw) {
    try {
        const parsed = JSON.parse(raw);
        if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
            return null;
        }
        const row = parsed;
        const partsRaw = Array.isArray(row.parts) ? row.parts : null;
        if (!partsRaw) {
            return null;
        }
        const parts = [];
        for (const item of partsRaw) {
            const part = parseNativeTextPart(item);
            if (!part) {
                return null;
            }
            parts.push(part);
        }
        return parts;
    }
    catch {
        return null;
    }
}
function toErrorReason(error) {
    return error instanceof Error ? error.message : String(error ?? 'unknown');
}
function requireNativeFunction(capability, exportName) {
    if (isNativeDisabledByEnv()) {
        throw makeNativeRequiredError(capability, 'native disabled');
    }
    const binding = loadNativeRouterHotpathBindingForInternalUse();
    const fn = binding?.[exportName];
    if (typeof fn !== 'function') {
        throw makeNativeRequiredError(capability);
    }
    return fn;
}
export function parseClockScheduleDirectiveCandidateWithNative(payload) {
    const capability = 'parseClockScheduleDirectiveCandidateJson';
    const fn = requireNativeFunction(capability, capability);
    let raw;
    try {
        raw = fn(payload);
    }
    catch (error) {
        throw makeNativeRequiredError(capability, toErrorReason(error));
    }
    if (typeof raw !== 'string' || !raw) {
        throw makeNativeRequiredError(capability, 'empty result');
    }
    if (raw.trim() === 'null') {
        return null;
    }
    const parsed = parseNativeCandidatePayload(raw);
    if (!parsed) {
        throw makeNativeRequiredError(capability, 'invalid payload');
    }
    return parsed;
}
export function extractClockScheduleDirectiveTextPartsWithNative(text) {
    const capability = 'extractClockScheduleDirectiveTextPartsJson';
    const fn = requireNativeFunction(capability, capability);
    let raw;
    try {
        raw = fn(String(text || ''));
    }
    catch (error) {
        throw makeNativeRequiredError(capability, toErrorReason(error));
    }
    if (typeof raw !== 'string' || !raw) {
        throw makeNativeRequiredError(capability, 'empty result');
    }
    const parsed = parseNativeTextPartsPayload(raw);
    if (!parsed) {
        throw makeNativeRequiredError(capability, 'invalid payload');
    }
    return parsed;
}
