import type {
	ExtensionAPI,
	ExtensionCommandContext,
	ExtensionContext,
} from "@singularity-forge/pi-coding-agent";

import {
	type AutoDashboardData,
	getAutoCommandContext,
	getAutoDashboardData,
	startAuto,
} from "../auto.js";
import { resetTransientRetryState } from "./agent-end-recovery.js";

type AutoResumeSnapshot = Pick<
	AutoDashboardData,
	"active" | "paused" | "stepMode" | "basePath"
>;

export interface ProviderErrorResumeDeps {
	getSnapshot(): AutoResumeSnapshot;
	resetTransientRetryState(): void;
	getCommandContext?(): ExtensionCommandContext | null;
	startAuto(
		ctx: ExtensionCommandContext,
		pi: ExtensionAPI,
		base: string,
		verboseMode: boolean,
		options?: { step?: boolean },
	): Promise<void>;
}

const defaultDeps: ProviderErrorResumeDeps = {
	getSnapshot: () => getAutoDashboardData(),
	resetTransientRetryState,
	getCommandContext: () => getAutoCommandContext(),
	startAuto,
};

export async function resumeAutoAfterProviderDelay(
	pi: ExtensionAPI,
	ctx: ExtensionContext,
	deps: ProviderErrorResumeDeps = defaultDeps,
): Promise<
	"resumed" | "already-active" | "not-paused" | "missing-base" | "missing-command-context"
> {
	const snapshot = deps.getSnapshot();

	if (snapshot.active) return "already-active";
	if (!snapshot.paused) return "not-paused";

	if (!snapshot.basePath) {
		ctx.ui.notify(
			"Provider error recovery delay elapsed, but no paused auto-mode base path was available. Leaving auto-mode paused.",
			"warning",
		);
		return "missing-base";
	}

	const commandCtx =
		typeof (ctx as Partial<ExtensionCommandContext>).newSession === "function"
			? (ctx as ExtensionCommandContext)
			: (deps.getCommandContext?.() ?? null);

	if (!commandCtx || typeof commandCtx.newSession !== "function") {
		ctx.ui.notify(
			"Provider error recovery delay elapsed, but no command context with newSession was available. Leaving auto-mode paused.",
			"warning",
		);
		return "missing-command-context";
	}

	// Reset the transient retry counter before restarting — without this,
	// consecutiveTransientCount accumulates across pause/resume cycles and
	// permanently locks out auto-resume after MAX_TRANSIENT_AUTO_RESUMES errors.
	deps.resetTransientRetryState();

	await deps.startAuto(
		commandCtx,
		pi,
		snapshot.basePath,
		false,
		{ step: snapshot.stepMode },
	);
	return "resumed";
}
