import { clearAgentActivityLeases, normalizeAgentActivityKind, setAgentActivityLease } from "./agent-activity-store.js";
const DEFAULT_AGENT_ID = "workflow-cannon";
const DEFAULT_SESSION_ID = "default";
const DEFAULT_TTL_SECONDS = 10 * 60;
function cleanText(value, fallback = "") {
    return typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback;
}
function detailsText(details, keys) {
    if (!details)
        return "";
    for (const key of keys) {
        const value = cleanText(details[key]);
        if (value)
            return value;
    }
    return "";
}
function positiveInteger(value) {
    const n = typeof value === "number" ? value : Number(value);
    return Number.isInteger(n) && n > 0 ? n : null;
}
function pullRequestNumberFromUrl(value) {
    const raw = cleanText(value);
    if (!raw)
        return null;
    const match = raw.match(/\/pull\/(\d+)(?:\b|$|[/?#])/);
    return match ? positiveInteger(match[1]) : null;
}
function resolvePullRequestNumber(args) {
    return (positiveInteger(args.prNumber) ??
        positiveInteger(args.details?.prNumber) ??
        positiveInteger(args.details?.pullRequestNumber) ??
        positiveInteger(args.details?.pr_number) ??
        pullRequestNumberFromUrl(args.details?.prUrl) ??
        pullRequestNumberFromUrl(args.details?.pullRequestUrl));
}
function resolveVersion(args) {
    return cleanText(args.version) || detailsText(args.details, ["releaseVersion", "version", "buildVersion"]);
}
function resolvePhaseKey(args) {
    return cleanText(args.phaseKey) || detailsText(args.details, ["phaseKey", "phase"]);
}
function formatPhaseLabel(phaseKey) {
    return /^phase\b/i.test(phaseKey) ? phaseKey : `Phase ${phaseKey}`;
}
function resolveReviewItem(args) {
    return (cleanText(args.taskId) ||
        detailsText(args.details, ["reviewItemId", "approvalItemId", "itemId", "taskId", "approvalId"]));
}
function resolveValidationLabel(args) {
    return detailsText(args.details, ["validationLabel", "validationCommand", "checkName"]) || cleanText(args.command);
}
function cleanTtlSeconds(value) {
    const n = typeof value === "number" ? value : Number(value);
    if (!Number.isFinite(n))
        return DEFAULT_TTL_SECONDS;
    return Math.min(60 * 60, Math.max(30, Math.floor(n)));
}
export function resolveAgentActivityIdentity(ctx, input = {}) {
    const agentId = cleanText(input.agentId, cleanText(ctx.resolvedActor, DEFAULT_AGENT_ID));
    const sessionId = cleanText(input.sessionId, cleanText(process.env.WORKSPACE_KIT_AGENT_SESSION_ID, DEFAULT_SESSION_ID));
    const activityId = cleanText(input.activityId, `current:${agentId}:${sessionId}`);
    return { agentId, sessionId, activityId };
}
export function buildAgentActivityLabel(args) {
    const taskId = cleanText(args.taskId);
    const command = cleanText(args.command);
    switch (args.kind) {
        case "planning":
            return "Planning Interview";
        case "blocked":
            return taskId ? `Blocked on Task ${taskId}` : "Blocked";
        case "working_task":
            return taskId ? `Working on Task ${taskId}` : "Working on Task";
        case "validating":
            return resolveValidationLabel(args) ? `Validating ${resolveValidationLabel(args)}` : "Validating";
        case "releasing":
            if (resolveVersion(args))
                return `Releasing Build ${resolveVersion(args)}`;
            if (resolvePhaseKey(args))
                return `Releasing ${formatPhaseLabel(resolvePhaseKey(args))}`;
            return "Releasing";
        case "reviewing_pr":
            return resolvePullRequestNumber(args) != null
                ? `Reviewing Pull Request ${String(resolvePullRequestNumber(args))}`
                : "Reviewing Pull Request";
        case "reviewing_item":
            return resolveReviewItem(args) ? `Reviewing Item ${resolveReviewItem(args)}` : "Reviewing Item";
        case "awaiting_policy_approval":
            return resolveReviewItem(args)
                ? `Awaiting Policy Approval for ${resolveReviewItem(args)}`
                : "Awaiting Policy Approval";
        case "awaiting_human_gate":
            return command ? `Awaiting Human Gate for ${command}` : "Awaiting Human Gate";
        case "delegating_task":
            return taskId ? `Delegating Task ${taskId}` : "Delegating Task";
        case "ready_task":
            return taskId ? `Ready Task ${taskId}` : "Ready Task";
        case "unavailable":
            return "Unavailable";
        case "awaiting_instruction":
        default:
            return "Awaiting Instruction";
    }
}
export function recordAgentActivity(ctx, planning, input) {
    if (!normalizeAgentActivityKind(input.kind)) {
        throw new Error(`Unsupported agent activity kind '${String(input.kind)}'`);
    }
    const identity = resolveAgentActivityIdentity(ctx, input);
    const now = cleanText(input.now, new Date().toISOString());
    const ttlMs = cleanTtlSeconds(input.ttlSeconds) * 1000;
    const expiresAt = new Date(Date.parse(now) + ttlMs).toISOString();
    const label = cleanText(input.label, buildAgentActivityLabel(input));
    const leaseInput = {
        ...identity,
        kind: input.kind,
        label,
        now,
        expiresAt,
        taskId: cleanText(input.taskId) || null,
        command: cleanText(input.command) || null,
        phaseKey: cleanText(input.phaseKey) || null,
        prNumber: input.prNumber ?? null,
        version: cleanText(input.version) || null,
        details: input.details ?? null
    };
    try {
        return setAgentActivityLease(planning.sqliteDual.getDatabase(), leaseInput);
    }
    catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        if (!leaseInput.taskId || !message.includes("FOREIGN KEY")) {
            throw err;
        }
        return setAgentActivityLease(planning.sqliteDual.getDatabase(), {
            ...leaseInput,
            taskId: null,
            details: { ...(leaseInput.details ?? {}), taskId: leaseInput.taskId }
        });
    }
}
export function recordAgentActivityBestEffort(ctx, planning, input) {
    try {
        return recordAgentActivity(ctx, planning, input);
    }
    catch {
        return null;
    }
}
export function clearAgentActivity(ctx, planning, input = {}) {
    const identity = resolveAgentActivityIdentity(ctx, input);
    return clearAgentActivityLeases(planning.sqliteDual.getDatabase(), {
        activityId: cleanText(input.activityId) || identity.activityId,
        agentId: cleanText(input.agentId) || undefined,
        sessionId: cleanText(input.sessionId) || undefined
    });
}
export function clearAgentActivityBestEffort(ctx, planning, input = {}) {
    try {
        return clearAgentActivity(ctx, planning, input);
    }
    catch {
        return 0;
    }
}
export function recordTaskTransitionActivityBestEffort(ctx, planning, args) {
    if (args.action === "start" || args.action === "unblock") {
        recordAgentActivityBestEffort(ctx, planning, {
            kind: "working_task",
            taskId: args.taskId,
            command: args.command,
            phaseKey: args.task?.phaseKey ?? null
        });
        return;
    }
    if (args.action === "block") {
        recordAgentActivityBestEffort(ctx, planning, {
            kind: "blocked",
            taskId: args.taskId,
            command: args.command,
            phaseKey: args.task?.phaseKey ?? null
        });
        return;
    }
    if (["complete", "pause", "cancel", "decline", "reject"].includes(args.action)) {
        clearAgentActivityBestEffort(ctx, planning, { taskId: args.taskId });
    }
}
